diff --git a/.typos.toml b/.typos.toml index 02a1f157a3a48..46fe0e19459f2 100644 --- a/.typos.toml +++ b/.typos.toml @@ -16,6 +16,7 @@ extend-exclude = [ "**/*.snap", "pnpm-lock.yaml", "**/*/CHANGELOG.md", + "Cargo.toml", ] [default.extend-words] @@ -24,6 +25,7 @@ trivia = "trivia" xdescribe = "xdescribe" seeked = "seeked" labeledby = "labeledby" +ser = "ser" [default.extend-identifiers] IIFEs = "IIFEs" diff --git a/Cargo.lock b/Cargo.lock index d13a36ae45137..914215cb2f10f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -69,7 +69,7 @@ checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -152,7 +152,7 @@ checksum = "9a8d5b11f7fa1068e5bbac8ab6c8c2c6940047f69185987446b60c995d4bf89c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -385,7 +385,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" dependencies = [ "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -570,7 +570,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -848,6 +848,29 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" +[[package]] +name = "layout_inspect" +version = "0.1.0" +source = "git+https://github.com/overlookmotel/layout_inspect?rev=5ba0afe#5ba0afe3df3024680421dcde1663e8621952c875" +dependencies = [ + "layout_inspect_derive", + "macro_rules_attribute", + "memoffset", + "regex", + "serde", +] + +[[package]] +name = "layout_inspect_derive" +version = "0.1.0" +source = "git+https://github.com/overlookmotel/layout_inspect?rev=5ba0afe#5ba0afe3df3024680421dcde1663e8621952c875" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -927,6 +950,22 @@ dependencies = [ "url", ] +[[package]] +name = "macro_rules_attribute" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf0c9b980bf4f3a37fd7b1c066941dd1b1d0152ce6ee6e8fe8c49b9f6810d862" +dependencies = [ + "macro_rules_attribute-proc_macro", + "paste", +] + +[[package]] +name = "macro_rules_attribute-proc_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58093314a45e00c77d5c508f76e77c3396afbbc0d01506e7fae47b018bac2b1d" + [[package]] name = "matchers" version = "0.1.0" @@ -942,6 +981,15 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "memoffset" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" +dependencies = [ + "autocfg", +] + [[package]] name = "miette" version = "7.2.0" @@ -964,7 +1012,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1043,7 +1091,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1058,7 +1106,7 @@ dependencies = [ "quote", "regex", "semver", - "syn", + "syn 2.0.60", ] [[package]] @@ -1162,7 +1210,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1207,6 +1255,7 @@ version = "0.12.5" dependencies = [ "allocator-api2", "bumpalo", + "layout_inspect", "serde", "serde_json", ] @@ -1216,8 +1265,10 @@ name = "oxc_ast" version = "0.12.5" dependencies = [ "bitflags 2.5.0", + "layout_inspect", "num-bigint", "oxc_allocator", + "oxc_macros", "oxc_span", "oxc_syntax", "serde", @@ -1334,6 +1385,15 @@ dependencies = [ "serde", ] +[[package]] +name = "oxc_inspect_ast" +version = "0.0.0" +dependencies = [ + "layout_inspect", + "oxc_ast", + "serde_json", +] + [[package]] name = "oxc_js_regex" version = "0.0.0" @@ -1408,7 +1468,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1586,6 +1646,7 @@ name = "oxc_span" version = "0.12.5" dependencies = [ "compact_str", + "layout_inspect", "miette", "serde", "tsify", @@ -1598,6 +1659,7 @@ version = "0.12.5" dependencies = [ "bitflags 2.5.0", "dashmap", + "layout_inspect", "oxc_index", "oxc_span", "phf", @@ -1694,6 +1756,12 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1731,7 +1799,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1785,7 +1853,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1820,7 +1888,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1852,7 +1920,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", "version_check", "yansi", ] @@ -2140,7 +2208,7 @@ checksum = "11bd257a6541e141e42ca6d24ae26f7714887b47e89aa739099104c7e4d3b7fc" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -2151,7 +2219,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -2174,7 +2242,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -2295,6 +2363,17 @@ dependencies = [ "is_ci", ] +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.60" @@ -2346,7 +2425,7 @@ checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -2411,7 +2490,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -2479,7 +2558,7 @@ checksum = "84fd902d4e0b9a4b27f2f440108dc034e1758628a9b702f8ec61ad66355422fa" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -2507,7 +2586,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -2571,7 +2650,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 2.0.60", ] [[package]] @@ -2750,7 +2829,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -2772,7 +2851,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] diff --git a/Cargo.toml b/Cargo.toml index 9992ca687b155..ab331ab6c53c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -166,6 +166,7 @@ serde_yaml = "0.9.34" similar = "2.5.0" textwrap = "0.16.0" unicode-width = "0.1.12" +layout_inspect = { git = "https://github.com/overlookmotel/layout_inspect", rev = "5ba0afe" } [workspace.metadata.cargo-shear] ignored = ["napi"] diff --git a/crates/oxc_allocator/Cargo.toml b/crates/oxc_allocator/Cargo.toml index be50acb8649a9..fcaeb8a2de8f9 100644 --- a/crates/oxc_allocator/Cargo.toml +++ b/crates/oxc_allocator/Cargo.toml @@ -23,6 +23,8 @@ allocator-api2 = { workspace = true } serde = { workspace = true, optional = true } +layout_inspect = { workspace = true, features = ["unique_names"] } + [dev-dependencies] serde = { workspace = true } serde_json = { workspace = true } diff --git a/crates/oxc_allocator/src/arena.rs b/crates/oxc_allocator/src/arena.rs index 69f8a5da6f45f..132edceefd6de 100644 --- a/crates/oxc_allocator/src/arena.rs +++ b/crates/oxc_allocator/src/arena.rs @@ -104,6 +104,29 @@ impl<'alloc, T: Hash> Hash for Box<'alloc, T> { } } +impl<'alloc, T: layout_inspect::Inspect + 'alloc> layout_inspect::Inspect for Box<'alloc, T> { + fn name() -> std::string::String { + "Box<".to_string() + &::name() + ">" + } + + fn size() -> Option { + Some(std::mem::size_of::()) + } + + fn align() -> Option { + Some(std::mem::align_of::()) + } + + fn def(collector: &mut layout_inspect::TypesCollector) -> layout_inspect::defs::DefType { + layout_inspect::defs::DefType::Box(layout_inspect::defs::DefBox { + name: ::name(), + size: ::size().unwrap(), + align: ::align().unwrap(), + value_type_id: collector.collect::(), + }) + } +} + /// Bumpalo Vec #[derive(Debug, PartialEq, Eq)] pub struct Vec<'alloc, T>(vec::Vec); @@ -207,6 +230,29 @@ impl<'alloc, T: Hash> Hash for Vec<'alloc, T> { } } +impl<'alloc, T: layout_inspect::Inspect + 'alloc> layout_inspect::Inspect for Vec<'alloc, T> { + fn name() -> std::string::String { + "Vec<".to_string() + &::name() + ">" + } + + fn size() -> Option { + Some(std::mem::size_of::()) + } + + fn align() -> Option { + Some(std::mem::align_of::()) + } + + fn def(collector: &mut layout_inspect::TypesCollector) -> layout_inspect::defs::DefType { + layout_inspect::defs::DefType::Vec(layout_inspect::defs::DefVec { + name: ::name(), + size: ::size().unwrap(), + align: ::align().unwrap(), + value_type_id: collector.collect::(), + }) + } +} + #[cfg(test)] mod test { use std::hash::{DefaultHasher, Hash, Hasher}; diff --git a/crates/oxc_ast/Cargo.toml b/crates/oxc_ast/Cargo.toml index 5390d97296377..64c84c751e022 100644 --- a/crates/oxc_ast/Cargo.toml +++ b/crates/oxc_ast/Cargo.toml @@ -21,10 +21,13 @@ doctest = false oxc_allocator = { workspace = true } oxc_span = { workspace = true } oxc_syntax = { workspace = true } +oxc_macros = { workspace = true } bitflags = { workspace = true } num-bigint = { workspace = true } +layout_inspect = { workspace = true, features = ["unique_names"] } + serde = { workspace = true, features = ["derive"], optional = true } serde_json = { workspace = true, optional = true } diff --git a/crates/oxc_ast/scripts/build.mjs b/crates/oxc_ast/scripts/build.mjs new file mode 100644 index 0000000000000..8905fb07212ed --- /dev/null +++ b/crates/oxc_ast/scripts/build.mjs @@ -0,0 +1,194 @@ +// Generate `Traverse` trait Rust code by parsing Rust type definitions. +// 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 {readFile, writeFile} from 'fs/promises'; +import {join as pathJoin} from 'path'; +import {fileURLToPath} from 'url'; +import assert from 'assert'; + +const types = await getTypesFromCode(); + +const traitCode = generateTraverseTraitCode(types); +await writeFile(pathJoin(fileURLToPath(import.meta.url), '../../src/traverse/traverse.rs'), traitCode); + +const ancestorCode = generateAncestorEnumCode(types); +await writeFile(pathJoin(fileURLToPath(import.meta.url), '../../src/traverse/ancestor.rs'), ancestorCode); + +function generateTraverseTraitCode(types) { + let methods = ''; + const addMethod = code => { methods += ` ${code}\n` }; + + for (const type of Object.values(types)) { + const snakeName = camelToSnake(type.name); + let ty = traversableTypeName(type), + isLeaf = false; + if (type.kind === 'struct') { + ty = `SharedBox<'a, ${ty}>`; + isLeaf = !type.fields.some(field => !!types[unwrapTypeName(field.type)]); + } + + if (isLeaf) { + addMethod(`fn visit_${snakeName}(&mut self, node: ${ty}, ctx: &TraverseCtx<'a>, tk: &mut Token) {}`); + } else { + addMethod(`fn enter_${snakeName}(&mut self, node: ${ty}, ctx: &TraverseCtx<'a>, tk: &mut Token) {}`); + addMethod(`fn exit_${snakeName}(&mut self, node: ${ty}, ctx: &TraverseCtx<'a>, tk: &mut Token) {}`); + } + methods += '\n'; + } + + const template = ` + // Generated by \`scripts/build.mjs\`. + + use super::{ast::*, cell::Token, SharedBox, TraverseCtx}; + + #[allow(unused_variables)] + pub trait Traverse<'a> { + [[methods]] + } + `.trimStart().split('\n').map(line => line.trim()).join('\n'); + + return template.replace('[[methods]]', methods.trimEnd()); +} + +function generateAncestorEnumCode(types) { + let variants = ''; + for (const type of Object.values(types)) { + if (type.kind !== 'struct') continue; + + for (const field of type.fields) { + const fieldType = types[unwrapTypeName(field.type)]; + if (!fieldType) continue; + const variantName = `${type.name}${snakeToCamel(field.name)}`; + variants += ` ${variantName}(SharedBox<'a, ${traversableTypeName(fieldType)}>),\n`; + } + } + + const template = ` + // Generated by \`scripts/build.mjs\`. + + use super::{ast::*, SharedBox}; + + /// Ancestor type used in traversable AST traversal. + /// + /// Encodes both the type of the parent, and child's location in the parent. + /// i.e. variants for \`BinaryExpressionLeft\` and \`BinaryExpressionRight\`, not just \`BinaryExpression\`. + #[derive(Clone, Copy)] + #[allow(dead_code)] // TODO: Remove this attr once is used + pub enum Ancestor<'a> { + [[variants]] + } + `.trimStart().split('\n').map(line => line.trim()).join('\n'); + + return template.replace('[[variants]]', variants.trimEnd()); +} + +async function getTypesFromCode() { + const codeDirPath = pathJoin(fileURLToPath(import.meta.url), '../../src/ast/'); + const filenames = ['js.rs', 'jsx.rs', 'literal.rs', 'ts.rs']; + + // Parse type defs from Rust files + const types = Object.create(null); + for (const filename of filenames) { + const code = await readFile(`${codeDirPath}${filename}`, 'utf8'), + lines = code.split(/\r?\n/); + for (let i = 0; i < lines.length; i++) { + if (lines[i] === '#[ast_node]') { + let match; + while (true) { + match = lines[++i].match(/^pub (enum|struct) (.+?)(<'a>)? \{/); + if (match) break; + } + const [, kind, name, lifetimeStr] = match, + hasLifetime = !!lifetimeStr; + const itemLines = []; + while (true) { + const line = lines[++i].replace(/\/\/.*$/, '').replace(/\s+/g, ' ').trim(); + if (line === '}') break; + if (line !== '') itemLines.push(line); + } + + if (kind === 'enum') { + const variants = [], + inherits = []; + for (const line of itemLines) { + const match = line.match(/^(.+?)\((.+?)\)(?: ?= ?(\d+))?,$/); + if (match) { + let [, name, type, discriminant] = match; + type = type.replace(/<'a>/g, '').replace(/<'a,\s*/g, '<'); + discriminant = discriminant ? +discriminant : null; + variants.push({name, type, discriminant}); + } else { + const match2 = line.match(/^@inherit ([A-Za-z]+)$/); + assert(match2, `Cannot parse line ${i} in '${filename}' as enum variant: '${line}'`); + inherits.push(match2[1]); + } + } + types[name] = {kind: 'enum', name, hasLifetime, variants, inherits}; + } else { + const fields = []; + for (let i = 0; i < itemLines.length; i++) { + const line = itemLines[i]; + if (line.startsWith('#[')) { + while (!itemLines[i].endsWith(']')) { + i++; + } + continue; + } + + const match = line.match(/^pub (?:r#)?([a-z_]+): (.+),(?: ?\/\/.+)?$/); + assert(match, `Cannot parse line ${i} in '${filename}' as struct field: '${line}'`); + let [, name, type] = match; + type = type.replace(/<'a>/g, '').replace(/<'a, ?/g, '<'); + fields.push({name, type}); + } + types[name] = {kind: 'struct', name, hasLifetime, fields}; + } + } + } + } + return types; +} + +function unwrapTypeName(name) { + outer: while (true) { + for (const wrapper of ['Box', 'Option', 'Vec', 'Cell']) { + if (name.startsWith(`${wrapper}<`)) { + name = name.slice(wrapper.length + 1, -1); + continue outer; + } + } + break; + } + return name; +} + +function traversableTypeName(type) { + let ty = `Traversable${type.name}`; + if (type.hasLifetime) ty += "<'a>"; + return ty; +} + +function camelToSnake(name) { + let prefixLen = 1; + for (const prefix of ['TS', 'JSX', 'JS']) { + if (name.startsWith(prefix)) { + prefixLen = prefix.length; + break; + } + } + return name.slice(0, prefixLen).toLowerCase() + + name.slice(prefixLen).replace(/[A-Z]/g, c => `_${c.toLowerCase()}`); +} + +function snakeToCamel(name) { + let prefixLen = 0; + for (const prefix of ['TS', 'JSX', 'JS']) { + if (name.startsWith(`${prefix.toLowerCase()}_`)) { + prefixLen = prefix.length + 1; + break; + } + } + return name.slice(0, prefixLen + 1).toUpperCase() + + name.slice(prefixLen + 1).replace(/_([a-z])/g, (_, c) => c.toUpperCase()); +} diff --git a/crates/oxc_ast/scripts/package.json b/crates/oxc_ast/scripts/package.json new file mode 100644 index 0000000000000..54340c04cab54 --- /dev/null +++ b/crates/oxc_ast/scripts/package.json @@ -0,0 +1,4 @@ +{ + "name": "oxc_ast_scripts", + "version": "0.0.0" +} diff --git a/crates/oxc_ast/src/ast/js.rs b/crates/oxc_ast/src/ast/js.rs index 2a6c0167a0739..a1c65db3f35f4 100644 --- a/crates/oxc_ast/src/ast/js.rs +++ b/crates/oxc_ast/src/ast/js.rs @@ -4,6 +4,7 @@ use std::{cell::Cell, fmt, hash::Hash}; use oxc_allocator::{Box, Vec}; +use oxc_macros::ast_node; use oxc_span::{Atom, CompactStr, SourceType, Span}; use oxc_syntax::{ operator::{ @@ -17,6 +18,9 @@ use serde::Serialize; #[cfg(feature = "serialize")] use tsify::Tsify; +use crate::dummy; +use crate::traverse::{ast::*, GCell, SharedBox, SharedVec, Token, Traverse, TraverseCtx}; + use super::inherit_variants; use super::{jsx::*, literal::*, ts::*}; @@ -37,6 +41,35 @@ export interface FormalParameterRest extends Span { } "#; +/// Traverse AST. +#[allow(unused_variables)] // TODO: Remove this attr once function is implemented +pub fn traverse<'a, T: Traverse<'a>>( + traverser: &mut T, + program: SharedBox<'a, TraversableProgram<'a>>, + ctx: &mut TraverseCtx<'a>, + tk: &mut Token, +) { + // TODO + // walk_traversable_program(traverser, program, ctx, tk); +} + +// TODO: Delete this - just for testing type layouts. +// The `inherit_variants!` macro has screwed up `layout_inspect` - it can't see these inherited types. +#[derive(layout_inspect::Inspect)] +pub enum FakeForTestingInheritedTypes<'a> { + Program(Box<'a, Program<'a>>), + MemberExpression(Box<'a, MemberExpression<'a>>), + Expression(Box<'a, Expression<'a>>), + SimpleAssignmentTarget(Box<'a, SimpleAssignmentTarget<'a>>), + AssignmentTargetPattern(Box<'a, AssignmentTargetPattern<'a>>), + AssignmentTarget(Box<'a, AssignmentTarget<'a>>), + Declaration(Box<'a, Declaration<'a>>), + ModuleDeclaration(Box<'a, ModuleDeclaration<'a>>), + TSType(Box<'a, TSTypeName<'a>>), + TSTypeName(Box<'a, TSTypeName<'a>>), +} + +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -45,7 +78,7 @@ pub struct Program<'a> { pub span: Span, pub source_type: SourceType, pub directives: Vec<'a, Directive<'a>>, - pub hashbang: Option>, + pub hashbang: Option>>, pub body: Vec<'a, Statement<'a>>, } @@ -65,6 +98,7 @@ inherit_variants! { /// Expression /// /// Inherits variants from [`MemberExpression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -389,7 +423,7 @@ impl<'a> Expression<'a> { } /// Identifier Name -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename = "Identifier"))] pub struct IdentifierName<'a> { @@ -405,6 +439,7 @@ impl<'a> IdentifierName<'a> { } /// Identifier Reference +#[ast_node] #[derive(Debug, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename = "Identifier"))] @@ -432,6 +467,7 @@ impl<'a> IdentifierReference<'a> { } /// Binding Identifier +#[ast_node] #[derive(Debug, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename = "Identifier"))] @@ -457,6 +493,7 @@ impl<'a> BindingIdentifier<'a> { } /// Label Identifier +#[ast_node] #[derive(Debug, Clone, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename = "Identifier"))] @@ -467,6 +504,7 @@ pub struct LabelIdentifier<'a> { } /// This Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -476,6 +514,7 @@ pub struct ThisExpression { } /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -494,6 +533,7 @@ inherit_variants! { /// Array Expression Element /// /// Inherits variants from [`Expression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize))] @@ -502,7 +542,7 @@ pub enum ArrayExpressionElement<'a> { SpreadElement(Box<'a, SpreadElement<'a>>) = 64, /// Array hole for sparse arrays /// - Elision(Elision) = 65, + Elision(Box<'a, Elision>) = 65, // `Expression` variants added here by `inherit_variants!` macro @inherit Expression } @@ -516,12 +556,14 @@ impl<'a> ArrayExpressionElement<'a> { /// Array Expression Elision Element /// Serialized as `null` in JSON AST. See `serialize.rs`. +#[ast_node] #[derive(Debug, Clone, Hash)] pub struct Elision { pub span: Span, } /// Object Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -540,6 +582,7 @@ impl<'a> ObjectExpression<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -548,16 +591,17 @@ pub enum ObjectPropertyKind<'a> { SpreadProperty(Box<'a, SpreadElement<'a>>), } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct ObjectProperty<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub kind: PropertyKind, pub key: PropertyKey<'a>, pub value: Expression<'a>, pub init: Option>, // for `CoverInitializedName` + pub kind: PropertyKind, pub method: bool, pub shorthand: bool, pub computed: bool, @@ -567,6 +611,7 @@ inherit_variants! { /// Property Key /// /// Inherits variants from [`Expression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -634,7 +679,7 @@ impl<'a> PropertyKey<'a> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))] pub enum PropertyKind { @@ -646,6 +691,7 @@ pub enum PropertyKind { /// Template Literal /// /// This is interpreted by interleaving the expression elements in between the quasi elements. +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -667,6 +713,7 @@ impl<'a> TemplateLiteral<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -674,10 +721,11 @@ pub struct TaggedTemplateExpression<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub tag: Expression<'a>, - pub quasi: TemplateLiteral<'a>, + pub quasi: Box<'a, TemplateLiteral<'a>>, pub type_parameters: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -689,7 +737,7 @@ pub struct TemplateElement<'a> { } /// See [template-strings-cooked-vs-raw](https://exploringjs.com/impatient-js/ch_template-literals.html#template-strings-cooked-vs-raw) -#[derive(Debug, Hash)] +#[derive(Debug, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct TemplateElementValue<'a> { /// A raw interpretation where backslashes do not have special meaning. @@ -704,6 +752,7 @@ pub struct TemplateElementValue<'a> { } /// +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -738,6 +787,7 @@ impl<'a> MemberExpression<'a> { MemberExpression::ComputedMemberExpression(expr) => expr.optional, MemberExpression::StaticMemberExpression(expr) => expr.optional, MemberExpression::PrivateFieldExpression(expr) => expr.optional, + MemberExpression::Dummy => dummy!(), } } @@ -746,6 +796,7 @@ impl<'a> MemberExpression<'a> { MemberExpression::ComputedMemberExpression(expr) => &expr.object, MemberExpression::StaticMemberExpression(expr) => &expr.object, MemberExpression::PrivateFieldExpression(expr) => &expr.object, + MemberExpression::Dummy => &Expression::Dummy, } } @@ -764,6 +815,7 @@ impl<'a> MemberExpression<'a> { }, MemberExpression::StaticMemberExpression(expr) => Some(expr.property.name.as_str()), MemberExpression::PrivateFieldExpression(_) => None, + MemberExpression::Dummy => dummy!(), } } @@ -784,6 +836,7 @@ impl<'a> MemberExpression<'a> { Some((expr.property.span, &expr.property.name)) } MemberExpression::PrivateFieldExpression(_) => None, + MemberExpression::Dummy => dummy!(), } } @@ -795,6 +848,7 @@ impl<'a> MemberExpression<'a> { let member_expr = x.expression.to_member_expression(); member_expr.object().without_parenthesized().is_specific_id(object) } + ChainElement::Dummy => dummy!(), }, x => x.is_specific_id(object), }; @@ -812,6 +866,7 @@ impl<'a> MemberExpression<'a> { } /// `MemberExpression[?Yield, ?Await] [ Expression[+In, ?Yield, ?Await] ]` +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -824,6 +879,7 @@ pub struct ComputedMemberExpression<'a> { } /// `MemberExpression[?Yield, ?Await] . IdentifierName` +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -831,11 +887,12 @@ pub struct StaticMemberExpression<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub object: Expression<'a>, - pub property: IdentifierName<'a>, + pub property: Box<'a, IdentifierName<'a>>, pub optional: bool, // for optional chaining } /// `MemberExpression[?Yield, ?Await] . PrivateIdentifier` +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -843,11 +900,12 @@ pub struct PrivateFieldExpression<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub object: Expression<'a>, - pub field: PrivateIdentifier<'a>, + pub field: Box<'a, PrivateIdentifier<'a>>, pub optional: bool, // for optional chaining } /// Call Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -909,6 +967,7 @@ impl<'a> CallExpression<'a> { } /// New Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -921,17 +980,19 @@ pub struct NewExpression<'a> { } /// Meta Property `new.target` | `import.meta` +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct MetaProperty<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub meta: IdentifierName<'a>, - pub property: IdentifierName<'a>, + pub meta: Box<'a, IdentifierName<'a>>, + pub property: Box<'a, IdentifierName<'a>>, } /// Spread Element +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -945,6 +1006,7 @@ inherit_variants! { /// Argument /// /// Inherits variants from [`Expression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -963,6 +1025,7 @@ impl Argument<'_> { } /// Update Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -975,6 +1038,7 @@ pub struct UpdateExpression<'a> { } /// Unary Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -986,6 +1050,7 @@ pub struct UnaryExpression<'a> { } /// Binary Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -998,18 +1063,20 @@ pub struct BinaryExpression<'a> { } /// Private Identifier in Shift Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct PrivateInExpression<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub left: PrivateIdentifier<'a>, + pub left: Box<'a, PrivateIdentifier<'a>>, pub operator: BinaryOperator, // BinaryOperator::In pub right: Expression<'a>, } /// Binary Logical Operators +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1022,6 +1089,7 @@ pub struct LogicalExpression<'a> { } /// Conditional Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1034,6 +1102,7 @@ pub struct ConditionalExpression<'a> { } /// Assignment Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1049,6 +1118,7 @@ inherit_variants! { /// Destructuring Assignment /// /// Inherits variants from [`SimpleAssignmentTarget`] and [`AssignmentTargetPattern`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1084,6 +1154,7 @@ inherit_variants! { /// Simple Assignment Target /// /// Inherits variants from [`MemberExpression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1128,6 +1199,7 @@ impl<'a> SimpleAssignmentTarget<'a> { } } +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1147,6 +1219,7 @@ macro_rules! match_assignment_target_pattern { pub use match_assignment_target_pattern; // See serializer in serialize.rs +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1159,7 +1232,7 @@ pub struct ArrayAssignmentTarget<'a> { )] pub elements: Vec<'a, Option>>, #[cfg_attr(feature = "serialize", serde(skip))] - pub rest: Option>, + pub rest: Option>>, #[cfg_attr(feature = "serialize", serde(skip))] pub trailing_comma: Option, } @@ -1174,6 +1247,7 @@ impl<'a> ArrayAssignmentTarget<'a> { } // See serializer in serialize.rs +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1186,7 +1260,7 @@ pub struct ObjectAssignmentTarget<'a> { )] pub properties: Vec<'a, AssignmentTargetProperty<'a>>, #[cfg_attr(feature = "serialize", serde(skip))] - pub rest: Option>, + pub rest: Option>>, } impl<'a> ObjectAssignmentTarget<'a> { @@ -1206,6 +1280,7 @@ impl<'a> ObjectAssignmentTarget<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename = "RestElement"))] @@ -1220,6 +1295,7 @@ inherit_variants! { /// Assignment Target Maybe Default /// /// Inherits variants from [`AssignmentTarget`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1247,6 +1323,7 @@ impl<'a> AssignmentTargetMaybeDefault<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1257,6 +1334,7 @@ pub struct AssignmentTargetWithDefault<'a> { pub init: Expression<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -1266,17 +1344,19 @@ pub enum AssignmentTargetProperty<'a> { } /// Assignment Property - Identifier Reference +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct AssignmentTargetPropertyIdentifier<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub binding: IdentifierReference<'a>, + pub binding: Box<'a, IdentifierReference<'a>>, pub init: Option>, } /// Assignment Property - Property Name +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1288,6 +1368,7 @@ pub struct AssignmentTargetPropertyProperty<'a> { } /// Sequence Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1297,6 +1378,7 @@ pub struct SequenceExpression<'a> { pub expressions: Vec<'a, Expression<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1306,6 +1388,7 @@ pub struct Super { } /// Await Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1315,6 +1398,7 @@ pub struct AwaitExpression<'a> { pub argument: Expression<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1328,6 +1412,7 @@ inherit_variants! { /// Chain Element /// /// Inherits variants from [`MemberExpression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1340,6 +1425,7 @@ pub enum ChainElement<'a> { } /// Parenthesized Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1353,6 +1439,7 @@ inherit_variants! { /// Statement /// /// Inherits variants from [`Declaration`] and [`ModuleDeclaration`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1398,13 +1485,14 @@ impl<'a> Statement<'a> { } /// Directive Prologue +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct Directive<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub expression: StringLiteral<'a>, + pub expression: Box<'a, StringLiteral<'a>>, /// A Use Strict Directive is an ExpressionStatement in a Directive Prologue whose StringLiteral is either of the exact code point sequences "use strict" or 'use strict'. /// A Use Strict Directive may not contain an EscapeSequence or LineContinuation. /// @@ -1412,6 +1500,7 @@ pub struct Directive<'a> { } /// Hashbang +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1422,6 +1511,7 @@ pub struct Hashbang<'a> { } /// Block Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1432,6 +1522,7 @@ pub struct BlockStatement<'a> { } /// Declarations and the Variable Statement +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1478,8 +1569,8 @@ impl<'a> Declaration<'a> { pub fn id(&self) -> Option<&BindingIdentifier<'a>> { match self { - Declaration::FunctionDeclaration(decl) => decl.id.as_ref(), - Declaration::ClassDeclaration(decl) => decl.id.as_ref(), + Declaration::FunctionDeclaration(decl) => decl.id.as_deref(), + Declaration::ClassDeclaration(decl) => decl.id.as_deref(), Declaration::TSTypeAliasDeclaration(decl) => Some(&decl.id), Declaration::TSInterfaceDeclaration(decl) => Some(&decl.id), Declaration::TSEnumDeclaration(decl) => Some(&decl.id), @@ -1503,6 +1594,7 @@ impl<'a> Declaration<'a> { } /// Variable Declaration +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -1521,7 +1613,7 @@ impl<'a> VariableDeclaration<'a> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))] pub enum VariableDeclarationKind { @@ -1559,6 +1651,7 @@ impl fmt::Display for VariableDeclarationKind { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1566,14 +1659,15 @@ pub struct VariableDeclarator<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, #[cfg_attr(feature = "serialize", serde(skip))] - pub kind: VariableDeclarationKind, - pub id: BindingPattern<'a>, + pub id: Box<'a, BindingPattern<'a>>, pub init: Option>, + pub kind: VariableDeclarationKind, pub definite: bool, } /// Using Declaration /// * +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -1586,6 +1680,7 @@ pub struct UsingDeclaration<'a> { } /// Empty Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1595,6 +1690,7 @@ pub struct EmptyStatement { } /// Expression Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1605,6 +1701,7 @@ pub struct ExpressionStatement<'a> { } /// If Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1617,6 +1714,7 @@ pub struct IfStatement<'a> { } /// Do-While Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1628,6 +1726,7 @@ pub struct DoWhileStatement<'a> { } /// While Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1639,6 +1738,7 @@ pub struct WhileStatement<'a> { } /// For Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1655,6 +1755,7 @@ inherit_variants! { /// For Statement Init /// /// Inherits variants from [`Expression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1676,6 +1777,7 @@ impl<'a> ForStatementInit<'a> { } /// For-In Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1688,6 +1790,7 @@ pub struct ForInStatement<'a> { } /// For-Of Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1704,6 +1807,7 @@ inherit_variants! { /// For Statement Left /// /// Inherits variants from [`AssignmentTarget`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1725,26 +1829,29 @@ impl<'a> ForStatementLeft<'a> { } /// Continue Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct ContinueStatement<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub label: Option>, + pub label: Option>>, } /// Break Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct BreakStatement<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub label: Option>, + pub label: Option>>, } /// Return Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1755,6 +1862,7 @@ pub struct ReturnStatement<'a> { } /// With Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1766,6 +1874,7 @@ pub struct WithStatement<'a> { } /// Switch Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1776,6 +1885,7 @@ pub struct SwitchStatement<'a> { pub cases: Vec<'a, SwitchCase<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1793,17 +1903,19 @@ impl<'a> SwitchCase<'a> { } /// Labelled Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct LabeledStatement<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub label: LabelIdentifier<'a>, + pub label: Box<'a, LabelIdentifier<'a>>, pub body: Statement<'a>, } /// Throw Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1814,6 +1926,7 @@ pub struct ThrowStatement<'a> { } /// Try Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1825,26 +1938,29 @@ pub struct TryStatement<'a> { pub finalizer: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct CatchClause<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub param: Option>, + pub param: Option>>, pub body: Box<'a, BlockStatement<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct CatchParameter<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub pattern: BindingPattern<'a>, + pub pattern: Box<'a, BindingPattern<'a>>, } /// Debugger Statement +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1855,6 +1971,7 @@ pub struct DebuggerStatement { /// Destructuring Binding Patterns /// * +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] @@ -1880,6 +1997,7 @@ impl<'a> BindingPattern<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -1919,17 +2037,19 @@ impl<'a> BindingPatternKind<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct AssignmentPattern<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub left: BindingPattern<'a>, + pub left: Box<'a, BindingPattern<'a>>, pub right: Expression<'a>, } // See serializer in serialize.rs +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1952,6 +2072,7 @@ impl<'a> ObjectPattern<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1959,12 +2080,13 @@ pub struct BindingProperty<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub key: PropertyKey<'a>, - pub value: BindingPattern<'a>, + pub value: Box<'a, BindingPattern<'a>>, pub shorthand: bool, pub computed: bool, } // See serializer in serialize.rs +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -1990,24 +2112,26 @@ impl<'a> ArrayPattern<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename = "RestElement"))] pub struct BindingRestElement<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub argument: BindingPattern<'a>, + pub argument: Box<'a, BindingPattern<'a>>, } /// Function Definitions +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub struct Function<'a> { - pub r#type: FunctionType, #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub id: Option>, + pub id: Option>>, + pub r#type: FunctionType, pub generator: bool, pub r#async: bool, /// Declaring `this` in a Function @@ -2025,7 +2149,7 @@ pub struct Function<'a> { /// return this.admin; /// }); /// ``` - pub this_param: Option>, + pub this_param: Option>>, pub params: Box<'a, FormalParameters<'a>>, pub body: Option>>, pub type_parameters: Option>>, @@ -2066,7 +2190,7 @@ impl<'a> Function<'a> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum FunctionType { FunctionDeclaration, @@ -2078,6 +2202,7 @@ pub enum FunctionType { /// // See serializer in serialize.rs +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2100,13 +2225,14 @@ impl<'a> FormalParameters<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct FormalParameter<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub pattern: BindingPattern<'a>, + pub pattern: Box<'a, BindingPattern<'a>>, pub accessibility: Option, pub readonly: bool, pub r#override: bool, @@ -2119,7 +2245,7 @@ impl<'a> FormalParameter<'a> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum FormalParameterKind { /// @@ -2145,6 +2271,7 @@ impl<'a> FormalParameters<'a> { } /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2162,6 +2289,7 @@ impl<'a> FunctionBody<'a> { } /// Arrow Function Definitions +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -2192,6 +2320,7 @@ impl<'a> ArrowFunctionExpression<'a> { } /// Generator Function Definitions +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2203,6 +2332,7 @@ pub struct YieldExpression<'a> { } /// Class Definitions +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] @@ -2210,7 +2340,7 @@ pub struct Class<'a> { pub r#type: ClassType, #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub id: Option>, + pub id: Option>>, pub super_class: Option>, pub body: Box<'a, ClassBody<'a>>, pub type_parameters: Option>>, @@ -2239,13 +2369,14 @@ impl<'a> Class<'a> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum ClassType { ClassDeclaration, ClassExpression, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2255,6 +2386,7 @@ pub struct ClassBody<'a> { pub body: Vec<'a, ClassElement<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -2273,6 +2405,7 @@ impl<'a> ClassElement<'a> { Self::MethodDefinition(def) => def.r#static, Self::PropertyDefinition(def) => def.r#static, Self::AccessorProperty(def) => def.r#static, + Self::Dummy => dummy!(), } } @@ -2282,6 +2415,7 @@ impl<'a> ClassElement<'a> { Self::MethodDefinition(def) => def.computed, Self::PropertyDefinition(def) => def.computed, Self::AccessorProperty(def) => def.computed, + Self::Dummy => dummy!(), } } @@ -2290,6 +2424,7 @@ impl<'a> ClassElement<'a> { Self::StaticBlock(_) | Self::TSIndexSignature(_) | Self::AccessorProperty(_) => None, Self::MethodDefinition(def) => def.accessibility, Self::PropertyDefinition(def) => def.accessibility, + Self::Dummy => dummy!(), } } @@ -2300,6 +2435,7 @@ impl<'a> ClassElement<'a> { | Self::PropertyDefinition(_) | Self::AccessorProperty(_) => None, Self::MethodDefinition(def) => Some(def.kind), + Self::Dummy => dummy!(), } } @@ -2309,6 +2445,7 @@ impl<'a> ClassElement<'a> { Self::MethodDefinition(def) => Some(&def.key), Self::PropertyDefinition(def) => Some(&def.key), Self::AccessorProperty(def) => Some(&def.key), + Self::Dummy => dummy!(), } } @@ -2318,6 +2455,7 @@ impl<'a> ClassElement<'a> { Self::MethodDefinition(def) => def.key.static_name(), Self::PropertyDefinition(def) => def.key.static_name(), Self::AccessorProperty(def) => def.key.static_name(), + Self::Dummy => dummy!(), } } @@ -2332,6 +2470,7 @@ impl<'a> ClassElement<'a> { | Self::AccessorProperty(_) | Self::TSIndexSignature(_) => false, Self::MethodDefinition(method) => method.value.body.is_none(), + Self::Dummy => dummy!(), } } @@ -2352,19 +2491,21 @@ impl<'a> ClassElement<'a> { Self::PropertyDefinition(property) => !property.decorators.is_empty(), Self::AccessorProperty(property) => !property.decorators.is_empty(), Self::StaticBlock(_) | Self::TSIndexSignature(_) => false, + Self::Dummy => dummy!(), } } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub struct MethodDefinition<'a> { - pub r#type: MethodDefinitionType, #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub key: PropertyKey<'a>, pub value: Box<'a, Function<'a>>, // FunctionExpression + pub r#type: MethodDefinitionType, pub kind: MethodDefinitionKind, pub computed: bool, pub r#static: bool, @@ -2374,22 +2515,23 @@ pub struct MethodDefinition<'a> { pub decorators: Vec<'a, Decorator<'a>>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum MethodDefinitionType { MethodDefinition, TSAbstractMethodDefinition, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub struct PropertyDefinition<'a> { - pub r#type: PropertyDefinitionType, #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub key: PropertyKey<'a>, pub value: Option>, + pub r#type: PropertyDefinitionType, pub computed: bool, pub r#static: bool, pub declare: bool, @@ -2402,14 +2544,14 @@ pub struct PropertyDefinition<'a> { pub decorators: Vec<'a, Decorator<'a>>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum PropertyDefinitionType { PropertyDefinition, TSAbstractPropertyDefinition, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))] pub enum MethodDefinitionKind { @@ -2431,6 +2573,7 @@ impl MethodDefinitionKind { } } +#[ast_node] #[derive(Debug, Clone, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2446,6 +2589,7 @@ impl<'a> PrivateIdentifier<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2455,6 +2599,7 @@ pub struct StaticBlock<'a> { pub body: Vec<'a, Statement<'a>>, } +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -2515,14 +2660,15 @@ impl<'a> ModuleDeclaration<'a> { match self { Self::ImportDeclaration(decl) => Some(&decl.source), Self::ExportAllDeclaration(decl) => Some(&decl.source), - Self::ExportNamedDeclaration(decl) => decl.source.as_ref(), + Self::ExportNamedDeclaration(decl) => decl.source.as_deref(), Self::ExportDefaultDeclaration(_) | Self::TSExportAssignment(_) | Self::TSNamespaceExportDeclaration(_) => None, + Self::Dummy => dummy!(), } } - pub fn with_clause(&self) -> Option<&WithClause<'a>> { + pub fn with_clause(&self) -> Option<&Box<'a, WithClause<'a>>> { match self { Self::ImportDeclaration(decl) => decl.with_clause.as_ref(), Self::ExportAllDeclaration(decl) => decl.with_clause.as_ref(), @@ -2530,10 +2676,12 @@ impl<'a> ModuleDeclaration<'a> { Self::ExportDefaultDeclaration(_) | Self::TSExportAssignment(_) | Self::TSNamespaceExportDeclaration(_) => None, + Self::Dummy => dummy!(), } } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2547,6 +2695,7 @@ pub struct AccessorProperty<'a> { pub decorators: Vec<'a, Decorator<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2557,6 +2706,7 @@ pub struct ImportExpression<'a> { pub arguments: Vec<'a, Expression<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -2565,13 +2715,14 @@ pub struct ImportDeclaration<'a> { pub span: Span, /// `None` for `import 'foo'`, `Some([])` for `import {} from 'foo'` pub specifiers: Option>>, - pub source: StringLiteral<'a>, + pub source: Box<'a, StringLiteral<'a>>, /// Some(vec![]) for empty assertion - pub with_clause: Option>, + pub with_clause: Option>>, /// `import type { foo } from 'bar'` pub import_kind: ImportOrExportKind, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -2587,6 +2738,7 @@ pub enum ImportDeclarationSpecifier<'a> { // import {imported} from "source" // import {imported as local} from "source" +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -2594,40 +2746,44 @@ pub struct ImportSpecifier<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub imported: ModuleExportName<'a>, - pub local: BindingIdentifier<'a>, + pub local: Box<'a, BindingIdentifier<'a>>, pub import_kind: ImportOrExportKind, } // import local from "source" +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct ImportDefaultSpecifier<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub local: BindingIdentifier<'a>, + pub local: Box<'a, BindingIdentifier<'a>>, } // import * as local from "source" +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct ImportNamespaceSpecifier<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub local: BindingIdentifier<'a>, + pub local: Box<'a, BindingIdentifier<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct WithClause<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub attributes_keyword: IdentifierName<'a>, // `with` or `assert` + pub attributes_keyword: Box<'a, IdentifierName<'a>>, // `with` or `assert` pub with_entries: Vec<'a, ImportAttribute<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2635,15 +2791,16 @@ pub struct ImportAttribute<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub key: ImportAttributeKey<'a>, - pub value: StringLiteral<'a>, + pub value: Box<'a, StringLiteral<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] pub enum ImportAttributeKey<'a> { - Identifier(IdentifierName<'a>), - StringLiteral(StringLiteral<'a>), + Identifier(Box<'a, IdentifierName<'a>>), + StringLiteral(Box<'a, StringLiteral<'a>>), } impl<'a> ImportAttributeKey<'a> { @@ -2651,10 +2808,12 @@ impl<'a> ImportAttributeKey<'a> { match self { Self::Identifier(identifier) => identifier.name.clone(), Self::StringLiteral(literal) => literal.value.clone(), + Self::Dummy => Atom::from("Dummy ImportAttributeKey"), } } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -2663,11 +2822,11 @@ pub struct ExportNamedDeclaration<'a> { pub span: Span, pub declaration: Option>, pub specifiers: Vec<'a, ExportSpecifier<'a>>, - pub source: Option>, + pub source: Option>>, /// `export type { foo }` pub export_kind: ImportOrExportKind, /// Some(vec![]) for empty assertion - pub with_clause: Option>, + pub with_clause: Option>>, } impl<'a> ExportNamedDeclaration<'a> { @@ -2681,6 +2840,7 @@ impl<'a> ExportNamedDeclaration<'a> { /// export default HoistableDeclaration /// export default ClassDeclaration /// export default AssignmentExpression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -2697,6 +2857,7 @@ impl<'a> ExportDefaultDeclaration<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -2704,9 +2865,9 @@ pub struct ExportAllDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub exported: Option>, - pub source: StringLiteral<'a>, - pub with_clause: Option>, // Some(vec![]) for empty assertion - pub export_kind: ImportOrExportKind, // `export type *` + pub source: Box<'a, StringLiteral<'a>>, + pub with_clause: Option>>, // Some(vec![]) for empty assertion + pub export_kind: ImportOrExportKind, // `export type *` } impl<'a> ExportAllDeclaration<'a> { @@ -2715,6 +2876,7 @@ impl<'a> ExportAllDeclaration<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -2736,6 +2898,7 @@ inherit_variants! { /// Export Default Declaration Kind /// /// Inherits variants from [`Expression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -2769,12 +2932,13 @@ impl<'a> ExportDefaultDeclarationKind<'a> { /// * `export {foo as "\0 any unicode"}` /// * es2022: /// * -#[derive(Debug, Clone, Hash)] +#[ast_node] +#[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] pub enum ModuleExportName<'a> { - Identifier(IdentifierName<'a>), - StringLiteral(StringLiteral<'a>), + Identifier(Box<'a, IdentifierName<'a>>), + StringLiteral(Box<'a, StringLiteral<'a>>), } impl<'a> fmt::Display for ModuleExportName<'a> { @@ -2782,16 +2946,26 @@ impl<'a> fmt::Display for ModuleExportName<'a> { let s = match self { Self::Identifier(identifier) => identifier.name.to_string(), Self::StringLiteral(literal) => format!(r#""{}""#, literal.value), + Self::Dummy => "Dummy ModuleExportName".to_string(), }; write!(f, "{s}") } } impl<'a> ModuleExportName<'a> { - pub fn name(&self) -> &Atom<'a> { + pub fn name(&self) -> Option<&Atom<'a>> { match self { - Self::Identifier(identifier) => &identifier.name, - Self::StringLiteral(literal) => &literal.value, + Self::Identifier(identifier) => Some(&identifier.name), + Self::StringLiteral(literal) => Some(&literal.value), + Self::Dummy => dummy!(), + } + } + + pub fn as_atom(&self) -> Atom<'a> { + match self { + Self::Identifier(identifier) => identifier.name.clone(), + Self::StringLiteral(literal) => literal.value.clone(), + Self::Dummy => Atom::from("Dummy ModuleExportName"), } } } diff --git a/crates/oxc_ast/src/ast/jsx.rs b/crates/oxc_ast/src/ast/jsx.rs index 5938d6a6f9ab6..116115f6a175c 100644 --- a/crates/oxc_ast/src/ast/jsx.rs +++ b/crates/oxc_ast/src/ast/jsx.rs @@ -4,6 +4,7 @@ #![allow(non_snake_case)] use oxc_allocator::{Box, Vec}; +use oxc_macros::ast_node; use oxc_span::{Atom, Span}; #[cfg(feature = "serialize")] use serde::Serialize; @@ -13,10 +14,14 @@ use tsify::Tsify; use super::{js::*, literal::*, ts::*}; use super::inherit_variants; +use crate::dummy; +use crate::traverse::ast::*; +use crate::traverse::{GCell, SharedBox, SharedVec}; // 1.2 JSX Elements /// JSX Element +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -29,6 +34,7 @@ pub struct JSXElement<'a> { } /// JSX Opening Element +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -42,6 +48,7 @@ pub struct JSXOpeningElement<'a> { } /// JSX Closing Element +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -52,6 +59,7 @@ pub struct JSXClosingElement<'a> { } /// JSX Fragment +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -63,7 +71,7 @@ pub struct JSXFragment<'a> { pub children: Vec<'a, JSXChild<'a>>, } -#[derive(Debug, Hash)] +#[derive(Debug, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct JSXOpeningFragment { @@ -71,7 +79,7 @@ pub struct JSXOpeningFragment { pub span: Span, } -#[derive(Debug, Hash)] +#[derive(Debug, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct JSXClosingFragment { @@ -80,6 +88,7 @@ pub struct JSXClosingFragment { } /// JSX Element Name +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -93,14 +102,15 @@ pub enum JSXElementName<'a> { } /// JSX Namespaced Name +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct JSXNamespacedName<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub namespace: JSXIdentifier<'a>, - pub property: JSXIdentifier<'a>, + pub namespace: Box<'a, JSXIdentifier<'a>>, + pub property: Box<'a, JSXIdentifier<'a>>, } impl<'a> std::fmt::Display for JSXNamespacedName<'a> { @@ -110,6 +120,7 @@ impl<'a> std::fmt::Display for JSXNamespacedName<'a> { } /// JSX Member Expression +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -117,18 +128,20 @@ pub struct JSXMemberExpression<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub object: JSXMemberExpressionObject<'a>, - pub property: JSXIdentifier<'a>, + pub property: Box<'a, JSXIdentifier<'a>>, } impl<'a> JSXMemberExpression<'a> { - pub fn get_object_identifier(&self) -> &JSXIdentifier { + pub fn get_object_identifier(&self) -> Option<&JSXIdentifier> { match &self.object { - JSXMemberExpressionObject::Identifier(ident) => ident, + JSXMemberExpressionObject::Identifier(ident) => Some(ident), JSXMemberExpressionObject::MemberExpression(expr) => expr.get_object_identifier(), + JSXMemberExpressionObject::Dummy => dummy!(), } } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -137,6 +150,7 @@ pub enum JSXMemberExpressionObject<'a> { MemberExpression(Box<'a, JSXMemberExpression<'a>>), } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -150,12 +164,13 @@ inherit_variants! { /// JSX Expression /// /// Inherits variants from [`Expression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] pub enum JSXExpression<'a> { - EmptyExpression(JSXEmptyExpression) = 64, + EmptyExpression(Box<'a, JSXEmptyExpression>) = 64, // `Expression` variants added here by `inherit_variants!` macro @inherit Expression } @@ -168,6 +183,7 @@ impl<'a> JSXExpression<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -179,6 +195,7 @@ pub struct JSXEmptyExpression { // 1.3 JSX Attributes /// JSX Attributes +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -188,6 +205,7 @@ pub enum JSXAttributeItem<'a> { } /// JSX Attribute +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -205,6 +223,7 @@ impl<'a> JSXAttribute<'a> { } /// JSX Spread Attribute +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -215,6 +234,7 @@ pub struct JSXSpreadAttribute<'a> { } /// JSX Attribute Name +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -224,6 +244,7 @@ pub enum JSXAttributeName<'a> { } /// JSX Attribute Value +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -234,6 +255,7 @@ pub enum JSXAttributeValue<'a> { Fragment(Box<'a, JSXFragment<'a>>), } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -252,6 +274,7 @@ impl<'a> JSXIdentifier<'a> { // 1.4 JSX Children /// JSX Child +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -263,6 +286,7 @@ pub enum JSXChild<'a> { Spread(Box<'a, JSXSpreadChild<'a>>), } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -272,6 +296,7 @@ pub struct JSXSpreadChild<'a> { pub expression: Expression<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] diff --git a/crates/oxc_ast/src/ast/literal.rs b/crates/oxc_ast/src/ast/literal.rs index fd3d9c5a2a9db..79f31e2c962f3 100644 --- a/crates/oxc_ast/src/ast/literal.rs +++ b/crates/oxc_ast/src/ast/literal.rs @@ -9,6 +9,7 @@ use std::{ }; use bitflags::bitflags; +use oxc_macros::ast_node; use oxc_span::{Atom, Span}; use oxc_syntax::number::{BigintBase, NumberBase}; #[cfg(feature = "serialize")] @@ -16,6 +17,9 @@ use serde::Serialize; #[cfg(feature = "serialize")] use tsify::Tsify; +use crate::traverse::GCell; + +#[ast_node] #[derive(Debug, Clone, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -39,6 +43,7 @@ impl BooleanLiteral { } } +#[ast_node] #[derive(Debug, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -59,6 +64,8 @@ impl NullLiteral { } } +// TODO: clone should only be removed from traversable version. +#[ast_node] #[derive(Debug, Clone)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -110,6 +117,7 @@ impl<'a> Hash for NumericLiteral<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -127,6 +135,7 @@ impl<'a> BigIntLiteral<'a> { } } +#[ast_node] #[derive(Debug, Clone, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -139,7 +148,7 @@ pub struct RegExpLiteral<'a> { pub regex: RegExp<'a>, } -#[derive(Debug, Clone, Hash)] +#[derive(Debug, Clone, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct RegExp<'a> { pub pattern: Atom<'a>, @@ -230,10 +239,33 @@ impl fmt::Display for RegExpFlags { } } -#[derive(Debug, Clone, Hash)] +impl layout_inspect::Inspect for RegExpFlags { + fn name() -> String { + "RegExpFlags".to_string() + } + + fn size() -> Option { + Some(std::mem::size_of::()) + } + + fn align() -> Option { + Some(std::mem::align_of::()) + } + + fn def(_collector: &mut layout_inspect::TypesCollector) -> layout_inspect::defs::DefType { + layout_inspect::defs::DefType::Primitive(layout_inspect::defs::DefPrimitive { + name: ::name(), + size: ::size().unwrap(), + align: ::align().unwrap(), + }) + } +} + +#[derive(Debug, Clone, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub struct EmptyObject; +#[ast_node] #[derive(Debug, Clone, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] diff --git a/crates/oxc_ast/src/ast/macros.rs b/crates/oxc_ast/src/ast/macros.rs index 49c7422c82fac..e9f269d9369a2 100644 --- a/crates/oxc_ast/src/ast/macros.rs +++ b/crates/oxc_ast/src/ast/macros.rs @@ -903,6 +903,7 @@ macro_rules! shared_enum_variants { // for `$child` and `$parent` are aligned match value { $($child::$variant(o) => $parent::$variant(o),)+ + $child::Dummy => $parent::Dummy, } } } diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index ea0b8ccff4c71..e53fd811e79a5 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -7,6 +7,7 @@ #![allow(non_snake_case)] use oxc_allocator::{Box, Vec}; +use oxc_macros::ast_node; use oxc_span::{Atom, GetSpan, Span}; #[cfg(feature = "serialize")] use serde::Serialize; @@ -14,6 +15,8 @@ use serde::Serialize; use tsify::Tsify; use super::{inherit_variants, js::*, jsx::*, literal::*}; +use crate::dummy; +use crate::traverse::{ast::*, GCell, SharedBox, SharedVec}; #[cfg(feature = "serialize")] #[wasm_bindgen::prelude::wasm_bindgen(typescript_custom_section)] @@ -25,31 +28,34 @@ export interface TSIndexSignatureName extends Span { } "#; +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSThisParameter<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub this: IdentifierName<'a>, + pub this: Box<'a, IdentifierName<'a>>, pub type_annotation: Option>>, } /// Enum Declaration /// /// `const_opt` enum `BindingIdentifier` { `EnumBody_opt` } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] pub struct TSEnumDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub id: BindingIdentifier<'a>, + pub id: Box<'a, BindingIdentifier<'a>>, pub members: Vec<'a, TSEnumMember<'a>>, /// Valid Modifiers: `const`, `export`, `declare` pub modifiers: Modifiers<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -64,6 +70,7 @@ inherit_variants! { /// TS Enum Member Name /// /// Inherits variants from [`Expression`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -79,6 +86,7 @@ pub enum TSEnumMemberName<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -88,6 +96,7 @@ pub struct TSTypeAnnotation<'a> { pub type_annotation: TSType<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -97,6 +106,7 @@ pub struct TSLiteralType<'a> { pub literal: TSLiteral<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged, rename_all = "camelCase"))] @@ -111,6 +121,7 @@ pub enum TSLiteral<'a> { UnaryExpression(Box<'a, UnaryExpression<'a>>), } +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -219,6 +230,7 @@ impl<'a> TSType<'a> { /// `SomeType extends OtherType ? TrueType : FalseType;` /// /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -234,6 +246,7 @@ pub struct TSConditionalType<'a> { /// string | string[] | (() => string) | { s: string } /// /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -246,6 +259,7 @@ pub struct TSUnionType<'a> { /// type `ColorfulCircle` = Colorful & Circle; /// /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -258,6 +272,7 @@ pub struct TSIntersectionType<'a> { /// keyof unique readonly /// /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -268,7 +283,7 @@ pub struct TSTypeOperator<'a> { pub type_annotation: TSType<'a>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))] pub enum TSTypeOperatorOperator { @@ -280,6 +295,7 @@ pub enum TSTypeOperatorOperator { /// `let myArray: string[] = ["hello", "world"];` /// /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -292,6 +308,7 @@ pub struct TSArrayType<'a> { /// `type I1 = Person["age" | "name"];` /// /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -305,6 +322,7 @@ pub struct TSIndexedAccessType<'a> { /// type `StringNumberPair` = [string, number]; /// /// +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -314,6 +332,7 @@ pub struct TSTupleType<'a> { pub element_types: Vec<'a, TSTupleElement<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -321,10 +340,11 @@ pub struct TSNamedTupleMember<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub element_type: TSType<'a>, - pub label: IdentifierName<'a>, + pub label: Box<'a, IdentifierName<'a>>, pub optional: bool, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -334,6 +354,7 @@ pub struct TSOptionalType<'a> { pub type_annotation: TSType<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -347,6 +368,7 @@ inherit_variants! { /// TS Tuple Element /// /// Inherits variants from [`TSType`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -361,6 +383,7 @@ pub enum TSTupleElement<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -369,6 +392,7 @@ pub struct TSAnyKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -377,6 +401,7 @@ pub struct TSStringKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -385,6 +410,7 @@ pub struct TSBooleanKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -393,6 +419,7 @@ pub struct TSNumberKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -401,6 +428,7 @@ pub struct TSNeverKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -409,6 +437,7 @@ pub struct TSUnknownKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -417,6 +446,7 @@ pub struct TSNullKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -425,6 +455,7 @@ pub struct TSUndefinedKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -433,6 +464,7 @@ pub struct TSVoidKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -441,6 +473,7 @@ pub struct TSSymbolKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -449,6 +482,7 @@ pub struct TSThisType { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -457,6 +491,7 @@ pub struct TSObjectKeyword { pub span: Span, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type"))] @@ -468,6 +503,7 @@ pub struct TSBigIntKeyword { /// type C = A; /// type D = B.a; /// type E = D.c.b.a; +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -481,6 +517,7 @@ pub struct TSTypeReference<'a> { /// TypeName: /// IdentifierReference /// NamespaceName . IdentifierReference +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -504,6 +541,8 @@ impl<'a> TSTypeName<'a> { match name { TSTypeName::IdentifierReference(name) => (*name).clone(), TSTypeName::QualifiedName(name) => TSTypeName::get_first_name(&name.left), + // TODO: consider adding a Dummy trait to sugar this into `T::Dummy()` + TSTypeName::Dummy => IdentifierReference::new(Span::default(), Atom::from("")), } } @@ -530,10 +569,12 @@ impl GetSpan for TSTypeName<'_> { match self { TSTypeName::IdentifierReference(ident) => ident.span, TSTypeName::QualifiedName(name) => name.span, + TSTypeName::Dummy => dummy!(), } } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -541,9 +582,10 @@ pub struct TSQualifiedName<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, pub left: TSTypeName<'a>, - pub right: IdentifierName<'a>, + pub right: Box<'a, IdentifierName<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -553,13 +595,14 @@ pub struct TSTypeParameterInstantiation<'a> { pub params: Vec<'a, TSType<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSTypeParameter<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub name: BindingIdentifier<'a>, + pub name: Box<'a, BindingIdentifier<'a>>, pub constraint: Option>, pub default: Option>, pub r#in: bool, @@ -567,6 +610,7 @@ pub struct TSTypeParameter<'a> { pub r#const: bool, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -576,20 +620,21 @@ pub struct TSTypeParameterDeclaration<'a> { pub params: Vec<'a, TSTypeParameter<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSTypeAliasDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub id: BindingIdentifier<'a>, + pub id: Box<'a, BindingIdentifier<'a>>, pub type_annotation: TSType<'a>, pub type_parameters: Option>>, /// Valid Modifiers: `declare`, `export` pub modifiers: Modifiers<'a>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))] pub enum TSAccessibility { @@ -598,6 +643,7 @@ pub enum TSAccessibility { Public, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -611,13 +657,14 @@ pub struct TSClassImplements<'a> { /// Interface Declaration /// /// interface `BindingIdentifier` `TypeParameters_opt` `InterfaceExtendsClause_opt` `ObjectType` +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSInterfaceDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub id: BindingIdentifier<'a>, + pub id: Box<'a, BindingIdentifier<'a>>, pub body: Box<'a, TSInterfaceBody<'a>>, pub type_parameters: Option>>, pub extends: Option>>, @@ -625,6 +672,7 @@ pub struct TSInterfaceDeclaration<'a> { pub modifiers: Modifiers<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -634,6 +682,7 @@ pub struct TSInterfaceBody<'a> { pub body: Vec<'a, TSSignature<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -647,6 +696,7 @@ pub struct TSPropertySignature<'a> { pub type_annotation: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged, rename_all = "camelCase"))] @@ -658,6 +708,7 @@ pub enum TSSignature<'a> { TSMethodSignature(Box<'a, TSMethodSignature<'a>>), } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -669,19 +720,20 @@ pub struct TSIndexSignature<'a> { pub readonly: bool, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSCallSignatureDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub this_param: Option>, + pub this_param: Option>>, pub params: Box<'a, FormalParameters<'a>>, pub return_type: Option>>, pub type_parameters: Option>>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))] pub enum TSMethodSignatureKind { @@ -690,6 +742,7 @@ pub enum TSMethodSignatureKind { Set, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -700,12 +753,13 @@ pub struct TSMethodSignature<'a> { pub computed: bool, pub optional: bool, pub kind: TSMethodSignatureKind, - pub this_param: Option>, + pub this_param: Option>>, pub params: Box<'a, FormalParameters<'a>>, pub return_type: Option>>, pub type_parameters: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -717,6 +771,7 @@ pub struct TSConstructSignatureDeclaration<'a> { pub type_parameters: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr( @@ -730,6 +785,7 @@ pub struct TSIndexSignatureName<'a> { pub type_annotation: Box<'a, TSTypeAnnotation<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -740,6 +796,7 @@ pub struct TSInterfaceHeritage<'a> { pub type_parameters: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -751,14 +808,16 @@ pub struct TSTypePredicate<'a> { pub type_annotation: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged, rename_all = "camelCase"))] pub enum TSTypePredicateName<'a> { Identifier(Box<'a, IdentifierName<'a>>), - This(TSThisType), + This(Box<'a, TSThisType>), } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -781,7 +840,7 @@ pub struct TSModuleDeclaration<'a> { pub modifiers: Modifiers<'a>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))] pub enum TSModuleDeclarationKind { @@ -790,23 +849,26 @@ pub enum TSModuleDeclarationKind { Namespace, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] pub enum TSModuleDeclarationName<'a> { - Identifier(IdentifierName<'a>), - StringLiteral(StringLiteral<'a>), + Identifier(Box<'a, IdentifierName<'a>>), + StringLiteral(Box<'a, StringLiteral<'a>>), } impl<'a> TSModuleDeclarationName<'a> { - pub fn name(&self) -> &Atom<'a> { + pub fn as_atom(&self) -> Atom<'a> { match self { - Self::Identifier(ident) => &ident.name, - Self::StringLiteral(lit) => &lit.value, + Self::Identifier(ident) => ident.name.clone(), + Self::StringLiteral(lit) => lit.value.clone(), + Self::Dummy => Atom::from("Dummy TSModuleDeclarationName"), } } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] @@ -815,6 +877,7 @@ pub enum TSModuleDeclarationBody<'a> { TSModuleBlock(Box<'a, TSModuleBlock<'a>>), } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -824,6 +887,7 @@ pub struct TSModuleBlock<'a> { pub body: Vec<'a, Statement<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -833,6 +897,7 @@ pub struct TSTypeLiteral<'a> { pub members: Vec<'a, TSSignature<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -842,6 +907,7 @@ pub struct TSInferType<'a> { pub type_parameter: Box<'a, TSTypeParameter<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -856,6 +922,7 @@ inherit_variants! { /// TS Type Query Expr Name /// /// Inherits variants from [`TSTypeName`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -867,6 +934,7 @@ pub enum TSTypeQueryExprName<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -875,10 +943,11 @@ pub struct TSImportType<'a> { pub span: Span, pub argument: TSType<'a>, pub qualifier: Option>, - pub attributes: Option>, + pub attributes: Option>>, pub type_parameters: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -888,6 +957,7 @@ pub struct TSImportAttributes<'a> { pub elements: Vec<'a, TSImportAttribute<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -898,26 +968,29 @@ pub struct TSImportAttribute<'a> { pub value: Expression<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(untagged))] pub enum TSImportAttributeName<'a> { - Identifier(IdentifierName<'a>), - StringLiteral(StringLiteral<'a>), + Identifier(Box<'a, IdentifierName<'a>>), + StringLiteral(Box<'a, StringLiteral<'a>>), } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSFunctionType<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub this_param: Option>, + pub this_param: Option>>, pub params: Box<'a, FormalParameters<'a>>, pub return_type: Box<'a, TSTypeAnnotation<'a>>, pub type_parameters: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -930,6 +1003,7 @@ pub struct TSConstructorType<'a> { pub type_parameters: Option>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -943,7 +1017,7 @@ pub struct TSMappedType<'a> { pub readonly: TSMappedTypeModifierOperator, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub enum TSMappedTypeModifierOperator { @@ -955,6 +1029,7 @@ pub enum TSMappedTypeModifierOperator { None, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -965,6 +1040,7 @@ pub struct TSTemplateLiteralType<'a> { pub types: Vec<'a, TSType<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -975,6 +1051,7 @@ pub struct TSAsExpression<'a> { pub type_annotation: TSType<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -985,6 +1062,7 @@ pub struct TSSatisfiesExpression<'a> { pub type_annotation: TSType<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -995,13 +1073,14 @@ pub struct TSTypeAssertion<'a> { pub type_annotation: TSType<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSImportEqualsDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub id: BindingIdentifier<'a>, + pub id: Box<'a, BindingIdentifier<'a>>, pub module_reference: TSModuleReference<'a>, pub import_kind: ImportOrExportKind, } @@ -1010,6 +1089,7 @@ inherit_variants! { /// TS Module Reference /// /// Inherits variants from [`TSTypeName`]. +#[ast_node] #[repr(C, u8)] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] @@ -1021,15 +1101,17 @@ pub enum TSModuleReference<'a> { } } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSExternalModuleReference<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub expression: StringLiteral<'a>, + pub expression: Box<'a, StringLiteral<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -1039,6 +1121,7 @@ pub struct TSNonNullExpression<'a> { pub expression: Expression<'a>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -1071,7 +1154,7 @@ impl<'a> Decorator<'a> { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub enum ModifierKind { @@ -1098,7 +1181,7 @@ impl ModifierKind { } } -#[derive(Debug, Hash)] +#[derive(Debug, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct Modifier { @@ -1107,26 +1190,28 @@ pub struct Modifier { pub kind: ModifierKind, } -#[derive(Debug, Default, Hash)] +#[derive(Debug, Default, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(transparent))] -pub struct Modifiers<'a>(Option>); +pub struct Modifiers<'a> { + inner: Option>, +} impl<'a> Modifiers<'a> { pub fn new(modifiers: Vec<'a, Modifier>) -> Self { - Self(Some(modifiers)) + Self { inner: Some(modifiers) } } pub fn empty() -> Self { - Self(None) + Self { inner: None } } pub fn is_none(&self) -> bool { - self.0.is_none() + self.inner.is_none() } pub fn contains(&self, target: ModifierKind) -> bool { - self.0 + self.inner .as_ref() .map_or(false, |modifiers| modifiers.iter().any(|modifier| modifier.kind == target)) } @@ -1136,7 +1221,7 @@ impl<'a> Modifiers<'a> { } pub fn remove_type_modifiers(&mut self) { - if let Some(list) = &mut self.0 { + if let Some(list) = &mut self.inner { list.retain(|m| !m.kind.is_typescript_syntax()); } } @@ -1145,6 +1230,7 @@ impl<'a> Modifiers<'a> { /// Export Assignment in non-module files /// /// `export = foo` +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -1157,15 +1243,17 @@ pub struct TSExportAssignment<'a> { /// Namespace Export Declaration in declaration files /// /// `export as namespace foo` +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] pub struct TSNamespaceExportDeclaration<'a> { #[cfg_attr(feature = "serialize", serde(flatten))] pub span: Span, - pub id: IdentifierName<'a>, + pub id: Box<'a, IdentifierName<'a>>, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -1176,7 +1264,7 @@ pub struct TSInstantiationExpression<'a> { pub type_parameters: Box<'a, TSTypeParameterInstantiation<'a>>, } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub enum ImportOrExportKind { @@ -1196,6 +1284,7 @@ impl ImportOrExportKind { // [`JSDoc`](https://github.com/microsoft/TypeScript/blob/54a554d8af2657630307cbfa8a3e4f3946e36507/src/compiler/types.ts#L393) +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] @@ -1206,6 +1295,7 @@ pub struct JSDocNullableType<'a> { pub postfix: bool, } +#[ast_node] #[derive(Debug, Hash)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(tag = "type", rename_all = "camelCase"))] diff --git a/crates/oxc_ast/src/ast_builder.rs b/crates/oxc_ast/src/ast_builder.rs index c12ab5c298a6f..3b2b85bbb8e3a 100644 --- a/crates/oxc_ast/src/ast_builder.rs +++ b/crates/oxc_ast/src/ast_builder.rs @@ -3,6 +3,7 @@ clippy::must_use_candidate, // must_use_candidate is too annoying for this file clippy::too_many_arguments, clippy::unused_self, + clippy::inconsistent_struct_constructor, )] use std::mem; @@ -120,7 +121,13 @@ impl<'a> AstBuilder<'a> { hashbang: Option>, body: Vec<'a, Statement<'a>>, ) -> Program<'a> { - Program { span, source_type, directives, hashbang, body } + Program { + span, + source_type, + directives, + hashbang: hashbang.map(|hashbang| self.alloc(hashbang)), + body, + } } /* ---------- Constructors ---------- */ @@ -242,7 +249,7 @@ impl<'a> AstBuilder<'a> { expression: StringLiteral<'a>, directive: Atom<'a>, ) -> Directive<'a> { - Directive { span, expression, directive } + Directive { span, expression: self.alloc(expression), directive } } pub fn hashbang(&self, span: Span, value: Atom<'a>) -> Hashbang<'a> { @@ -259,14 +266,18 @@ impl<'a> AstBuilder<'a> { ) } - pub fn break_statement(&self, span: Span, label: Option>) -> Statement<'a> { + pub fn break_statement( + &self, + span: Span, + label: Option>>, + ) -> Statement<'a> { Statement::BreakStatement(self.alloc(BreakStatement { span, label })) } pub fn continue_statement( &self, span: Span, - label: Option>, + label: Option>>, ) -> Statement<'a> { Statement::ContinueStatement(self.alloc(ContinueStatement { span, label })) } @@ -346,7 +357,7 @@ impl<'a> AstBuilder<'a> { pub fn labeled_statement( &self, span: Span, - label: LabelIdentifier<'a>, + label: Box<'a, LabelIdentifier<'a>>, body: Statement<'a>, ) -> Statement<'a> { Statement::LabeledStatement(self.alloc(LabeledStatement { span, label, body })) @@ -394,11 +405,11 @@ impl<'a> AstBuilder<'a> { param: Option>, body: Box<'a, BlockStatement<'a>>, ) -> Box<'a, CatchClause<'a>> { - self.alloc(CatchClause { span, param, body }) + self.alloc(CatchClause { span, param: param.map(|param| self.alloc(param)), body }) } pub fn catch_parameter(&self, span: Span, pattern: BindingPattern<'a>) -> CatchParameter<'a> { - CatchParameter { span, pattern } + CatchParameter { span, pattern: self.alloc(pattern) } } pub fn while_statement( @@ -431,7 +442,11 @@ impl<'a> AstBuilder<'a> { meta: IdentifierName<'a>, property: IdentifierName<'a>, ) -> Expression<'a> { - Expression::MetaProperty(self.alloc(MetaProperty { span, meta, property })) + Expression::MetaProperty(self.alloc(MetaProperty { + span, + meta: self.alloc(meta), + property: self.alloc(property), + })) } pub fn array_expression( @@ -641,7 +656,7 @@ impl<'a> AstBuilder<'a> { MemberExpression::StaticMemberExpression(self.alloc(StaticMemberExpression { span, object, - property, + property: self.alloc(property), optional, })) } @@ -660,7 +675,7 @@ impl<'a> AstBuilder<'a> { &self, span: Span, object: Expression<'a>, - field: PrivateIdentifier<'a>, + field: Box<'a, PrivateIdentifier<'a>>, optional: bool, ) -> MemberExpression<'a> { MemberExpression::PrivateFieldExpression(self.alloc(PrivateFieldExpression { @@ -674,7 +689,7 @@ impl<'a> AstBuilder<'a> { pub fn private_in_expression( &self, span: Span, - left: PrivateIdentifier<'a>, + left: Box<'a, PrivateIdentifier<'a>>, right: Expression<'a>, ) -> Expression<'a> { Expression::PrivateInExpression(self.alloc(PrivateInExpression { @@ -689,7 +704,7 @@ impl<'a> AstBuilder<'a> { &self, span: Span, object: Expression<'a>, - field: PrivateIdentifier<'a>, + field: Box<'a, PrivateIdentifier<'a>>, optional: bool, ) -> Expression<'a> { self.member_expression(self.private_field(span, object, field, optional)) @@ -759,7 +774,7 @@ impl<'a> AstBuilder<'a> { &self, span: Span, tag: Expression<'a>, - quasi: TemplateLiteral<'a>, + quasi: Box<'a, TemplateLiteral<'a>>, type_parameters: Option>>, ) -> Expression<'a> { Expression::TaggedTemplateExpression(self.alloc(TaggedTemplateExpression { @@ -846,7 +861,14 @@ impl<'a> AstBuilder<'a> { r#override: bool, decorators: Vec<'a, Decorator<'a>>, ) -> FormalParameter<'a> { - FormalParameter { span, pattern, accessibility, readonly, r#override, decorators } + FormalParameter { + span, + pattern: self.alloc(pattern), + accessibility, + readonly, + r#override, + decorators, + } } pub fn ts_this_parameter( @@ -854,8 +876,8 @@ impl<'a> AstBuilder<'a> { span: Span, this: IdentifierName<'a>, type_annotation: Option>>, - ) -> TSThisParameter<'a> { - TSThisParameter { span, this, type_annotation } + ) -> Box<'a, TSThisParameter<'a>> { + self.alloc(TSThisParameter { span, this: self.alloc(this), type_annotation }) } pub fn plain_function( @@ -888,7 +910,7 @@ impl<'a> AstBuilder<'a> { id: Option>, generator: bool, r#async: bool, - this_param: Option>, + this_param: Option>>, params: Box<'a, FormalParameters<'a>>, body: Option>>, type_parameters: Option>>, @@ -898,7 +920,7 @@ impl<'a> AstBuilder<'a> { self.alloc(Function { r#type, span, - id, + id: id.map(|id| self.alloc(id)), generator, r#async, this_param, @@ -937,7 +959,7 @@ impl<'a> AstBuilder<'a> { self.alloc(Class { r#type, span, - id, + id: id.map(|id| self.alloc(id)), super_class, body, type_parameters, @@ -1049,7 +1071,7 @@ impl<'a> AstBuilder<'a> { init: Option>, definite: bool, ) -> VariableDeclarator<'a> { - VariableDeclarator { span, kind, id, init, definite } + VariableDeclarator { span, kind, id: self.alloc(id), init, definite } } pub fn using_declaration( @@ -1096,7 +1118,7 @@ impl<'a> AstBuilder<'a> { shorthand: bool, computed: bool, ) -> BindingProperty<'a> { - BindingProperty { span, key, value, shorthand, computed } + BindingProperty { span, key, value: self.alloc(value), shorthand, computed } } pub fn spread_element( @@ -1122,7 +1144,7 @@ impl<'a> AstBuilder<'a> { left: BindingPattern<'a>, right: Expression<'a>, ) -> BindingPattern<'a> { - let pattern = self.alloc(AssignmentPattern { span, left, right }); + let pattern = self.alloc(AssignmentPattern { span, left: self.alloc(left), right }); BindingPattern { kind: BindingPatternKind::AssignmentPattern(pattern), type_annotation: None, @@ -1135,7 +1157,7 @@ impl<'a> AstBuilder<'a> { span: Span, argument: BindingPattern<'a>, ) -> Box<'a, BindingRestElement<'a>> { - self.alloc(BindingRestElement { span, argument }) + self.alloc(BindingRestElement { span, argument: self.alloc(argument) }) } pub fn property_key_identifier(&self, ident: IdentifierName<'a>) -> PropertyKey<'a> { @@ -1157,10 +1179,16 @@ impl<'a> AstBuilder<'a> { span: Span, specifiers: Option>>, source: StringLiteral<'a>, - with_clause: Option>, + with_clause: Option>>, import_kind: ImportOrExportKind, ) -> Box<'a, ImportDeclaration<'a>> { - self.alloc(ImportDeclaration { span, specifiers, source, with_clause, import_kind }) + self.alloc(ImportDeclaration { + span, + specifiers, + source: self.alloc(source), + with_clause, + import_kind, + }) } pub fn export_all_declaration( @@ -1168,10 +1196,16 @@ impl<'a> AstBuilder<'a> { span: Span, exported: Option>, source: StringLiteral<'a>, - with_clause: Option>, + with_clause: Option>>, export_kind: ImportOrExportKind, ) -> Box<'a, ExportAllDeclaration<'a>> { - self.alloc(ExportAllDeclaration { span, exported, source, with_clause, export_kind }) + self.alloc(ExportAllDeclaration { + span, + exported, + source: self.alloc(source), + with_clause, + export_kind, + }) } pub fn export_default_declaration( @@ -1190,13 +1224,13 @@ impl<'a> AstBuilder<'a> { specifiers: Vec<'a, ExportSpecifier<'a>>, source: Option>, export_kind: ImportOrExportKind, - with_clause: Option>, + with_clause: Option>>, ) -> Box<'a, ExportNamedDeclaration<'a>> { self.alloc(ExportNamedDeclaration { span, declaration, specifiers, - source, + source: source.map(|source| self.alloc(source)), export_kind, with_clause, }) @@ -1284,8 +1318,8 @@ impl<'a> AstBuilder<'a> { pub fn jsx_namespaced_name( &self, span: Span, - namespace: JSXIdentifier<'a>, - property: JSXIdentifier<'a>, + namespace: Box<'a, JSXIdentifier<'a>>, + property: Box<'a, JSXIdentifier<'a>>, ) -> Box<'a, JSXNamespacedName<'a>> { self.alloc(JSXNamespacedName { span, namespace, property }) } @@ -1294,7 +1328,7 @@ impl<'a> AstBuilder<'a> { &self, span: Span, object: JSXMemberExpressionObject<'a>, - property: JSXIdentifier<'a>, + property: Box<'a, JSXIdentifier<'a>>, ) -> Box<'a, JSXMemberExpression<'a>> { self.alloc(JSXMemberExpression { span, object, property }) } @@ -1315,8 +1349,8 @@ impl<'a> AstBuilder<'a> { self.alloc(JSXSpreadChild { span, expression }) } - pub fn jsx_empty_expression(&self, span: Span) -> JSXEmptyExpression { - JSXEmptyExpression { span } + pub fn jsx_empty_expression(&self, span: Span) -> Box<'a, JSXEmptyExpression> { + self.alloc(JSXEmptyExpression { span }) } pub fn jsx_attribute( @@ -1336,8 +1370,8 @@ impl<'a> AstBuilder<'a> { self.alloc(JSXSpreadAttribute { span, argument }) } - pub fn jsx_identifier(&self, span: Span, name: Atom<'a>) -> JSXIdentifier<'a> { - JSXIdentifier { span, name } + pub fn jsx_identifier(&self, span: Span, name: Atom<'a>) -> Box<'a, JSXIdentifier<'a>> { + self.alloc(JSXIdentifier { span, name }) } pub fn jsx_text(&self, span: Span, value: Atom<'a>) -> Box<'a, JSXText<'a>> { @@ -1442,7 +1476,7 @@ impl<'a> AstBuilder<'a> { out: bool, r#const: bool, ) -> TSTypeParameter<'a> { - TSTypeParameter { span, name, constraint, default, r#in, out, r#const } + TSTypeParameter { span, name: self.alloc(name), constraint, default, r#in, out, r#const } } pub fn ts_type_parameters( @@ -1512,7 +1546,7 @@ impl<'a> AstBuilder<'a> { pub fn ts_call_signature_declaration( &self, span: Span, - this_param: Option>, + this_param: Option>>, params: Box<'a, FormalParameters<'a>>, return_type: Option>>, type_parameters: Option>>, @@ -1548,7 +1582,7 @@ impl<'a> AstBuilder<'a> { computed: bool, optional: bool, kind: TSMethodSignatureKind, - this_param: Option>, + this_param: Option>>, params: Box<'a, FormalParameters<'a>>, return_type: Option>>, type_parameters: Option>>, @@ -1630,7 +1664,7 @@ impl<'a> AstBuilder<'a> { ) -> Declaration<'a> { Declaration::TSImportEqualsDeclaration(self.alloc(TSImportEqualsDeclaration { span, - id, + id: self.alloc(id), module_reference, import_kind, })) @@ -1647,7 +1681,7 @@ impl<'a> AstBuilder<'a> { ) -> Declaration<'a> { Declaration::TSInterfaceDeclaration(self.alloc(TSInterfaceDeclaration { span, - id, + id: self.alloc(id), body, type_parameters, extends, @@ -1665,7 +1699,7 @@ impl<'a> AstBuilder<'a> { ) -> Declaration<'a> { Declaration::TSTypeAliasDeclaration(self.alloc(TSTypeAliasDeclaration { span, - id, + id: self.alloc(id), type_annotation, type_parameters, modifiers, @@ -1681,7 +1715,7 @@ impl<'a> AstBuilder<'a> { ) -> Declaration<'a> { Declaration::TSEnumDeclaration(self.alloc(TSEnumDeclaration { span, - id, + id: self.alloc(id), members, modifiers, })) @@ -1802,7 +1836,7 @@ impl<'a> AstBuilder<'a> { span: Span, argument: TSType<'a>, qualifier: Option>, - attributes: Option>, + attributes: Option>>, type_parameters: Option>>, ) -> TSType<'a> { TSType::TSImportType(self.alloc(TSImportType { @@ -1834,7 +1868,7 @@ impl<'a> AstBuilder<'a> { pub fn ts_function_type( &self, span: Span, - this_param: Option>, + this_param: Option>>, params: Box<'a, FormalParameters<'a>>, return_type: Box<'a, TSTypeAnnotation<'a>>, type_parameters: Option>>, @@ -1914,7 +1948,7 @@ impl<'a> AstBuilder<'a> { } pub fn ts_type_predicate_name_this(&self, ty: TSThisType) -> TSTypePredicateName<'a> { - TSTypePredicateName::This(ty) + TSTypePredicateName::This(self.alloc(ty)) } pub fn ts_type_predicate_name_identifier( diff --git a/crates/oxc_ast/src/ast_kind.rs b/crates/oxc_ast/src/ast_kind.rs index 551ee88b61a06..de9d2c2fba784 100644 --- a/crates/oxc_ast/src/ast_kind.rs +++ b/crates/oxc_ast/src/ast_kind.rs @@ -2,17 +2,20 @@ use oxc_span::{Atom, GetSpan, Span}; #[allow(clippy::wildcard_imports)] use crate::ast::*; +use crate::dummy; macro_rules! ast_kinds { { $($ident:ident($type:ty),)* } => ( #[derive(Debug, Clone, Copy)] pub enum AstType { + Dummy, $($ident,)* } /// Untyped AST Node Kind #[derive(Debug, Clone, Copy)] pub enum AstKind<'a> { + Dummy, $($ident($type),)* } ) @@ -350,6 +353,7 @@ impl<'a> AstKind<'a> { Expression::TSTypeAssertion(e) => Self::TSTypeAssertion(e), Expression::TSNonNullExpression(e) => Self::TSNonNullExpression(e), Expression::TSInstantiationExpression(e) => Self::TSInstantiationExpression(e), + Expression::Dummy => Self::Dummy, } } } @@ -535,6 +539,7 @@ impl<'a> GetSpan for AstKind<'a> { Self::TSNamedTupleMember(x) => x.span, Self::TSPropertySignature(x) => x.span, + Self::Dummy => dummy!(), } } } @@ -737,6 +742,7 @@ impl<'a> AstKind<'a> { Self::TSNamedTupleMember(_) => "TSNamedTupleMember".into(), Self::TSPropertySignature(_) => "TSPropertySignature".into(), + Self::Dummy => "Dummy AstKind".into(), } } } diff --git a/crates/oxc_ast/src/dummy.rs b/crates/oxc_ast/src/dummy.rs new file mode 100644 index 0000000000000..ac7debe69485b --- /dev/null +++ b/crates/oxc_ast/src/dummy.rs @@ -0,0 +1,18 @@ +#[macro_export] +macro_rules! dummy { + () => { + Default::default() + }; + + (panic) => { + dummy!(@ panic) + }; + + (unreachable) => { + dummy!(@ unreachable) + }; + + (@ $macro:ident) => { + $macro!("Unexpected `Dummy` ast node.") + }; +} diff --git a/crates/oxc_ast/src/lib.rs b/crates/oxc_ast/src/lib.rs index 680f983508556..637c8545a7357 100644 --- a/crates/oxc_ast/src/lib.rs +++ b/crates/oxc_ast/src/lib.rs @@ -15,9 +15,11 @@ mod serialize; pub mod ast; mod ast_builder; mod ast_kind; +mod dummy; pub mod precedence; mod span; pub mod syntax_directed_operations; +mod traverse; mod trivia; pub mod visit; diff --git a/crates/oxc_ast/src/serialize.rs b/crates/oxc_ast/src/serialize.rs index fbbf1bccdae1b..b49a9c583b36f 100644 --- a/crates/oxc_ast/src/serialize.rs +++ b/crates/oxc_ast/src/serialize.rs @@ -72,8 +72,12 @@ impl<'a> Serialize for ArrayAssignmentTarget<'a> { struct SerArrayAssignmentTarget<'a, 'b> { #[serde(flatten)] span: Span, - elements: - ElementsAndRest<'a, 'b, Option>, AssignmentTargetRest<'a>>, + elements: ElementsAndRest< + 'a, + 'b, + Option>, + Box<'a, AssignmentTargetRest<'a>>, + >, } impl<'a> Serialize for ObjectAssignmentTarget<'a> { @@ -91,7 +95,8 @@ impl<'a> Serialize for ObjectAssignmentTarget<'a> { struct SerObjectAssignmentTarget<'a, 'b> { #[serde(flatten)] span: Span, - properties: ElementsAndRest<'a, 'b, AssignmentTargetProperty<'a>, AssignmentTargetRest<'a>>, + properties: + ElementsAndRest<'a, 'b, AssignmentTargetProperty<'a>, Box<'a, AssignmentTargetRest<'a>>>, } impl<'a> Serialize for ObjectPattern<'a> { diff --git a/crates/oxc_ast/src/span.rs b/crates/oxc_ast/src/span.rs index bc4fb1994ede2..d1ed281d79d36 100644 --- a/crates/oxc_ast/src/span.rs +++ b/crates/oxc_ast/src/span.rs @@ -1,6 +1,6 @@ use oxc_span::{GetSpan, Span}; -use crate::ast::*; +use crate::{ast::*, dummy}; impl<'a> GetSpan for Statement<'a> { fn span(&self) -> Span { @@ -40,6 +40,7 @@ impl<'a> GetSpan for Statement<'a> { Self::TSEnumDeclaration(decl) => decl.span, Self::TSModuleDeclaration(decl) => decl.span, Self::TSImportEqualsDeclaration(decl) => decl.span, + Self::Dummy => dummy!(), } } } @@ -90,6 +91,7 @@ impl<'a> GetSpan for Expression<'a> { Self::ComputedMemberExpression(e) => e.span, Self::StaticMemberExpression(e) => e.span, Self::PrivateFieldExpression(e) => e.span, + Self::Dummy => dummy!(), } } } @@ -107,6 +109,7 @@ impl<'a> GetSpan for BindingPatternKind<'a> { Self::ObjectPattern(pat) => pat.span, Self::ArrayPattern(pat) => pat.span, Self::AssignmentPattern(pat) => pat.span, + Self::Dummy => dummy!(), } } } @@ -118,6 +121,7 @@ impl<'a> GetSpan for BindingPattern<'a> { BindingPatternKind::ObjectPattern(pat) => pat.span, BindingPatternKind::ArrayPattern(pat) => pat.span, BindingPatternKind::AssignmentPattern(pat) => pat.span, + BindingPatternKind::Dummy => dummy!(), } } } @@ -136,6 +140,7 @@ impl<'a> GetSpan for ClassElement<'a> { Self::PropertyDefinition(def) => def.span, Self::AccessorProperty(def) => def.span, Self::TSIndexSignature(sig) => sig.span, + Self::Dummy => dummy!(), } } } @@ -188,6 +193,7 @@ impl<'a> GetSpan for PropertyKey<'a> { Self::ComputedMemberExpression(e) => e.span, Self::StaticMemberExpression(e) => e.span, Self::PrivateFieldExpression(e) => e.span, + Self::Dummy => dummy!(), } } } @@ -198,6 +204,7 @@ impl<'a> GetSpan for MemberExpression<'a> { Self::ComputedMemberExpression(expr) => expr.span, Self::StaticMemberExpression(expr) => expr.span, Self::PrivateFieldExpression(expr) => expr.span, + Self::Dummy => dummy!(), } } } @@ -207,6 +214,7 @@ impl<'a> GetSpan for ImportAttributeKey<'a> { match self { Self::Identifier(identifier) => identifier.span, Self::StringLiteral(literal) => literal.span, + Self::Dummy => dummy!(), } } } @@ -216,6 +224,7 @@ impl<'a> GetSpan for ModuleExportName<'a> { match self { Self::Identifier(identifier) => identifier.span, Self::StringLiteral(literal) => literal.span, + Self::Dummy => dummy!(), } } } @@ -229,6 +238,7 @@ impl<'a> GetSpan for ModuleDeclaration<'a> { Self::ExportNamedDeclaration(decl) => decl.span, Self::TSExportAssignment(decl) => decl.span, Self::TSNamespaceExportDeclaration(decl) => decl.span, + Self::Dummy => dummy!(), } } } @@ -245,6 +255,7 @@ impl<'a> GetSpan for Declaration<'a> { Self::TSEnumDeclaration(decl) => decl.span, Self::TSModuleDeclaration(decl) => decl.span, Self::TSImportEqualsDeclaration(decl) => decl.span, + Self::Dummy => dummy!(), } } } @@ -254,6 +265,7 @@ impl<'a> GetSpan for TSModuleDeclarationName<'a> { match self { Self::Identifier(ident) => ident.span, Self::StringLiteral(lit) => lit.span, + Self::Dummy => dummy!(), } } } @@ -263,6 +275,7 @@ impl<'a> GetSpan for ObjectPropertyKind<'a> { match self { Self::ObjectProperty(p) => p.span, Self::SpreadProperty(p) => p.span, + Self::Dummy => dummy!(), } } } @@ -282,6 +295,7 @@ impl<'a> GetSpan for AssignmentTarget<'a> { Self::PrivateFieldExpression(expr) => expr.span, Self::ArrayAssignmentTarget(pat) => pat.span, Self::ObjectAssignmentTarget(pat) => pat.span, + Self::Dummy => dummy!(), } } } @@ -291,6 +305,7 @@ impl<'a> GetSpan for AssignmentTargetProperty<'a> { match self { Self::AssignmentTargetPropertyIdentifier(identifier) => identifier.span, Self::AssignmentTargetPropertyProperty(literal) => literal.span, + Self::Dummy => dummy!(), } } } @@ -342,6 +357,7 @@ impl<'a> GetSpan for Argument<'a> { Self::ComputedMemberExpression(e) => e.span, Self::StaticMemberExpression(e) => e.span, Self::PrivateFieldExpression(e) => e.span, + Self::Dummy => dummy!(), } } } @@ -395,6 +411,7 @@ impl<'a> GetSpan for ArrayExpressionElement<'a> { Self::PrivateFieldExpression(e) => e.span, Self::Elision(elision) => elision.span, + Self::Dummy => dummy!(), } } } @@ -447,6 +464,7 @@ impl<'a> GetSpan for ForStatementInit<'a> { Self::ComputedMemberExpression(e) => e.span, Self::StaticMemberExpression(e) => e.span, Self::PrivateFieldExpression(e) => e.span, + Self::Dummy => dummy!(), } } } @@ -467,6 +485,7 @@ impl<'a> GetSpan for ForStatementLeft<'a> { Self::ArrayAssignmentTarget(x) => x.span, Self::ObjectAssignmentTarget(x) => x.span, Self::UsingDeclaration(x) => x.span, + Self::Dummy => dummy!(), } } } @@ -483,6 +502,7 @@ impl<'a> GetSpan for SimpleAssignmentTarget<'a> { Self::ComputedMemberExpression(expr) => expr.span, Self::StaticMemberExpression(expr) => expr.span, Self::PrivateFieldExpression(expr) => expr.span, + Self::Dummy => dummy!(), } } } @@ -493,6 +513,7 @@ impl<'a> GetSpan for JSXElementName<'a> { Self::Identifier(ident) => ident.span, Self::NamespacedName(name) => name.span, Self::MemberExpression(expr) => expr.span, + Self::Dummy => dummy!(), } } } @@ -511,6 +532,7 @@ impl<'a> GetSpan for TSSignature<'a> { Self::TSCallSignatureDeclaration(decl) => decl.span, Self::TSConstructSignatureDeclaration(decl) => decl.span, Self::TSMethodSignature(sig) => sig.span, + Self::Dummy => dummy!(), } } } @@ -553,6 +575,7 @@ impl<'a> GetSpan for TSType<'a> { Self::TSObjectKeyword(t) => t.span, Self::JSDocNullableType(t) => t.span, Self::JSDocUnknownType(t) => t.span, + Self::Dummy => dummy!(), } } } @@ -607,6 +630,7 @@ impl<'a> GetSpan for ExportDefaultDeclarationKind<'a> { Self::ComputedMemberExpression(e) => e.span, Self::StaticMemberExpression(e) => e.span, Self::PrivateFieldExpression(e) => e.span, + Self::Dummy => dummy!(), } } } @@ -617,6 +641,7 @@ impl<'a> GetSpan for ImportDeclarationSpecifier<'a> { Self::ImportSpecifier(specifier) => specifier.span, Self::ImportDefaultSpecifier(specifier) => specifier.span, Self::ImportNamespaceSpecifier(specifier) => specifier.span, + Self::Dummy => dummy!(), } } } @@ -629,6 +654,7 @@ impl<'a> GetSpan for JSXChild<'a> { Self::Text(text) => text.span, Self::Fragment(fragment) => fragment.span, Self::Spread(spread) => spread.span, + Self::Dummy => dummy!(), } } } @@ -638,6 +664,7 @@ impl<'a> GetSpan for AssignmentTargetPattern<'a> { match &self { Self::ArrayAssignmentTarget(x) => x.span, Self::ObjectAssignmentTarget(x) => x.span, + Self::Dummy => dummy!(), } } } @@ -647,6 +674,7 @@ impl<'a> GetSpan for JSXAttributeItem<'a> { match &self { JSXAttributeItem::Attribute(attr) => attr.span, JSXAttributeItem::SpreadAttribute(attr) => attr.span, + JSXAttributeItem::Dummy => dummy!(), } } } @@ -698,6 +726,7 @@ impl<'a> GetSpan for JSXExpression<'a> { Self::ComputedMemberExpression(e) => e.span, Self::StaticMemberExpression(e) => e.span, Self::PrivateFieldExpression(e) => e.span, + Self::Dummy => dummy!(), } } } @@ -707,6 +736,7 @@ impl<'a> GetSpan for JSXAttributeName<'a> { match &self { JSXAttributeName::Identifier(ident) => ident.span, JSXAttributeName::NamespacedName(namespaced_name) => namespaced_name.span, + JSXAttributeName::Dummy => dummy!(), } } } @@ -718,6 +748,7 @@ impl<'a> GetSpan for JSXAttributeValue<'a> { JSXAttributeValue::ExpressionContainer(container) => container.span, JSXAttributeValue::Fragment(fragment) => fragment.span, JSXAttributeValue::Element(element) => element.span, + JSXAttributeValue::Dummy => dummy!(), } } } @@ -727,6 +758,7 @@ impl<'a> GetSpan for JSXMemberExpressionObject<'a> { match &self { JSXMemberExpressionObject::Identifier(ident) => ident.span, JSXMemberExpressionObject::MemberExpression(expr) => expr.span, + JSXMemberExpressionObject::Dummy => dummy!(), } } } diff --git a/crates/oxc_ast/src/syntax_directed_operations/bound_names.rs b/crates/oxc_ast/src/syntax_directed_operations/bound_names.rs index 30b71941b17c3..6e7c592731b05 100644 --- a/crates/oxc_ast/src/syntax_directed_operations/bound_names.rs +++ b/crates/oxc_ast/src/syntax_directed_operations/bound_names.rs @@ -1,4 +1,4 @@ -use crate::ast::*; +use crate::{ast::*, dummy}; /// [`BoundName`](https://tc39.es/ecma262/#sec-static-semantics-boundnames) pub trait BoundName<'a> { @@ -16,6 +16,7 @@ impl<'a> BoundNames<'a> for BindingPattern<'a> { BindingPatternKind::ArrayPattern(array) => array.bound_names(f), BindingPatternKind::ObjectPattern(object) => object.bound_names(f), BindingPatternKind::AssignmentPattern(assignment) => assignment.bound_names(f), + BindingPatternKind::Dummy => dummy!(), } } } @@ -156,6 +157,7 @@ impl<'a> BoundNames<'a> for ImportDeclaration<'a> { ImportDeclarationSpecifier::ImportNamespaceSpecifier(specifier) => { f(&specifier.local); } + ImportDeclarationSpecifier::Dummy => dummy!(), } } } diff --git a/crates/oxc_ast/src/syntax_directed_operations/gather_node_parts.rs b/crates/oxc_ast/src/syntax_directed_operations/gather_node_parts.rs index 3fb1758468e1b..4634ef97f1d07 100644 --- a/crates/oxc_ast/src/syntax_directed_operations/gather_node_parts.rs +++ b/crates/oxc_ast/src/syntax_directed_operations/gather_node_parts.rs @@ -1,4 +1,4 @@ -use crate::ast::*; +use crate::{ast::*, dummy}; use oxc_span::Atom; // TODO: @@ -34,6 +34,7 @@ impl<'a> GatherNodeParts<'a> for MemberExpression<'a> { expr.object.gather(f); expr.field.gather(f); } + MemberExpression::Dummy => dummy!(), } } } @@ -45,6 +46,7 @@ impl<'a> GatherNodeParts<'a> for AssignmentTarget<'a> { self.to_simple_assignment_target().gather(f); } match_assignment_target_pattern!(Self) => {} + Self::Dummy => dummy!(), } } } diff --git a/crates/oxc_ast/src/syntax_directed_operations/private_bound_identifiers.rs b/crates/oxc_ast/src/syntax_directed_operations/private_bound_identifiers.rs index 4c1a1ee026e86..0e39504066878 100644 --- a/crates/oxc_ast/src/syntax_directed_operations/private_bound_identifiers.rs +++ b/crates/oxc_ast/src/syntax_directed_operations/private_bound_identifiers.rs @@ -1,4 +1,4 @@ -use crate::ast::*; +use crate::{ast::*, dummy}; /// [`PrivateBoundIdentifiers`](https://tc39.es/ecma262/#sec-static-semantics-privateboundidentifiers) pub trait PrivateBoundIdentifiers { @@ -12,6 +12,7 @@ impl<'a> PrivateBoundIdentifiers for ClassElement<'a> { ClassElement::MethodDefinition(def) => def.private_bound_identifiers(), ClassElement::PropertyDefinition(def) => def.private_bound_identifiers(), ClassElement::AccessorProperty(def) => def.private_bound_identifiers(), + ClassElement::Dummy => dummy!(), } } } diff --git a/crates/oxc_ast/src/syntax_directed_operations/prop_name.rs b/crates/oxc_ast/src/syntax_directed_operations/prop_name.rs index 0b56af7261372..5e44b24a66e64 100644 --- a/crates/oxc_ast/src/syntax_directed_operations/prop_name.rs +++ b/crates/oxc_ast/src/syntax_directed_operations/prop_name.rs @@ -1,6 +1,6 @@ use oxc_span::Span; -use crate::ast::*; +use crate::{ast::*, dummy}; /// [`PropName`](https://tc39.es/ecma262/#sec-static-semantics-propname) pub trait PropName { @@ -12,6 +12,7 @@ impl<'a> PropName for ObjectPropertyKind<'a> { match self { ObjectPropertyKind::ObjectProperty(prop) => prop.prop_name(), ObjectPropertyKind::SpreadProperty(_) => None, + ObjectPropertyKind::Dummy => dummy!(), } } } diff --git a/crates/oxc_ast/src/traverse/ancestor.rs b/crates/oxc_ast/src/traverse/ancestor.rs new file mode 100644 index 0000000000000..202bdd82f248a --- /dev/null +++ b/crates/oxc_ast/src/traverse/ancestor.rs @@ -0,0 +1,305 @@ +// Generated by `scripts/build.js`. + +use super::{ast::*, SharedBox}; + +/// Ancestor type used in traversable AST traversal. +/// +/// Encodes both the type of the parent, and child's location in the parent. +/// i.e. variants for `BinaryExpressionLeft` and `BinaryExpressionRight`, not just `BinaryExpression`. +#[derive(Clone, Copy)] +#[allow(dead_code)] // TODO: Remove this attr once is used +pub enum Ancestor<'a> { + ProgramDirectives(SharedBox<'a, TraversableDirective<'a>>), + ProgramHashbang(SharedBox<'a, TraversableHashbang<'a>>), + ProgramBody(SharedBox<'a, TraversableStatement<'a>>), + ArrayExpressionElements(SharedBox<'a, TraversableArrayExpressionElement<'a>>), + ObjectExpressionProperties(SharedBox<'a, TraversableObjectPropertyKind<'a>>), + ObjectPropertyKey(SharedBox<'a, TraversablePropertyKey<'a>>), + ObjectPropertyValue(SharedBox<'a, TraversableExpression<'a>>), + ObjectPropertyInit(SharedBox<'a, TraversableExpression<'a>>), + TemplateLiteralQuasis(SharedBox<'a, TraversableTemplateElement<'a>>), + TemplateLiteralExpressions(SharedBox<'a, TraversableExpression<'a>>), + TaggedTemplateExpressionTag(SharedBox<'a, TraversableExpression<'a>>), + TaggedTemplateExpressionQuasi(SharedBox<'a, TraversableTemplateLiteral<'a>>), + TaggedTemplateExpressionTypeParameters( + SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>, + ), + ComputedMemberExpressionObject(SharedBox<'a, TraversableExpression<'a>>), + ComputedMemberExpressionExpression(SharedBox<'a, TraversableExpression<'a>>), + StaticMemberExpressionObject(SharedBox<'a, TraversableExpression<'a>>), + PrivateFieldExpressionObject(SharedBox<'a, TraversableExpression<'a>>), + PrivateFieldExpressionField(SharedBox<'a, TraversablePrivateIdentifier<'a>>), + CallExpressionCallee(SharedBox<'a, TraversableExpression<'a>>), + CallExpressionArguments(SharedBox<'a, TraversableArgument<'a>>), + CallExpressionTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + NewExpressionCallee(SharedBox<'a, TraversableExpression<'a>>), + NewExpressionArguments(SharedBox<'a, TraversableArgument<'a>>), + NewExpressionTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + SpreadElementArgument(SharedBox<'a, TraversableExpression<'a>>), + UpdateExpressionArgument(SharedBox<'a, TraversableSimpleAssignmentTarget<'a>>), + UnaryExpressionArgument(SharedBox<'a, TraversableExpression<'a>>), + BinaryExpressionLeft(SharedBox<'a, TraversableExpression<'a>>), + BinaryExpressionRight(SharedBox<'a, TraversableExpression<'a>>), + PrivateInExpressionLeft(SharedBox<'a, TraversablePrivateIdentifier<'a>>), + PrivateInExpressionRight(SharedBox<'a, TraversableExpression<'a>>), + LogicalExpressionLeft(SharedBox<'a, TraversableExpression<'a>>), + LogicalExpressionRight(SharedBox<'a, TraversableExpression<'a>>), + ConditionalExpressionTest(SharedBox<'a, TraversableExpression<'a>>), + ConditionalExpressionConsequent(SharedBox<'a, TraversableExpression<'a>>), + ConditionalExpressionAlternate(SharedBox<'a, TraversableExpression<'a>>), + AssignmentExpressionLeft(SharedBox<'a, TraversableAssignmentTarget<'a>>), + AssignmentExpressionRight(SharedBox<'a, TraversableExpression<'a>>), + ArrayAssignmentTargetElements(SharedBox<'a, TraversableAssignmentTargetMaybeDefault<'a>>), + ArrayAssignmentTargetRest(SharedBox<'a, TraversableAssignmentTargetRest<'a>>), + ObjectAssignmentTargetProperties(SharedBox<'a, TraversableAssignmentTargetProperty<'a>>), + ObjectAssignmentTargetRest(SharedBox<'a, TraversableAssignmentTargetRest<'a>>), + AssignmentTargetRestTarget(SharedBox<'a, TraversableAssignmentTarget<'a>>), + AssignmentTargetWithDefaultBinding(SharedBox<'a, TraversableAssignmentTarget<'a>>), + AssignmentTargetWithDefaultInit(SharedBox<'a, TraversableExpression<'a>>), + AssignmentTargetPropertyIdentifierBinding(SharedBox<'a, TraversableIdentifierReference<'a>>), + AssignmentTargetPropertyIdentifierInit(SharedBox<'a, TraversableExpression<'a>>), + AssignmentTargetPropertyPropertyName(SharedBox<'a, TraversablePropertyKey<'a>>), + AssignmentTargetPropertyPropertyBinding( + SharedBox<'a, TraversableAssignmentTargetMaybeDefault<'a>>, + ), + SequenceExpressionExpressions(SharedBox<'a, TraversableExpression<'a>>), + AwaitExpressionArgument(SharedBox<'a, TraversableExpression<'a>>), + ChainExpressionExpression(SharedBox<'a, TraversableChainElement<'a>>), + ParenthesizedExpressionExpression(SharedBox<'a, TraversableExpression<'a>>), + DirectiveExpression(SharedBox<'a, TraversableStringLiteral<'a>>), + BlockStatementBody(SharedBox<'a, TraversableStatement<'a>>), + VariableDeclarationDeclarations(SharedBox<'a, TraversableVariableDeclarator<'a>>), + VariableDeclaratorId(SharedBox<'a, TraversableBindingPattern<'a>>), + VariableDeclaratorInit(SharedBox<'a, TraversableExpression<'a>>), + UsingDeclarationDeclarations(SharedBox<'a, TraversableVariableDeclarator<'a>>), + ExpressionStatementExpression(SharedBox<'a, TraversableExpression<'a>>), + IfStatementTest(SharedBox<'a, TraversableExpression<'a>>), + IfStatementConsequent(SharedBox<'a, TraversableStatement<'a>>), + IfStatementAlternate(SharedBox<'a, TraversableStatement<'a>>), + DoWhileStatementBody(SharedBox<'a, TraversableStatement<'a>>), + DoWhileStatementTest(SharedBox<'a, TraversableExpression<'a>>), + WhileStatementTest(SharedBox<'a, TraversableExpression<'a>>), + WhileStatementBody(SharedBox<'a, TraversableStatement<'a>>), + ForStatementInit(SharedBox<'a, TraversableForStatementInit<'a>>), + ForStatementTest(SharedBox<'a, TraversableExpression<'a>>), + ForStatementUpdate(SharedBox<'a, TraversableExpression<'a>>), + ForStatementBody(SharedBox<'a, TraversableStatement<'a>>), + ForInStatementLeft(SharedBox<'a, TraversableForStatementLeft<'a>>), + ForInStatementRight(SharedBox<'a, TraversableExpression<'a>>), + ForInStatementBody(SharedBox<'a, TraversableStatement<'a>>), + ForOfStatementLeft(SharedBox<'a, TraversableForStatementLeft<'a>>), + ForOfStatementRight(SharedBox<'a, TraversableExpression<'a>>), + ForOfStatementBody(SharedBox<'a, TraversableStatement<'a>>), + ContinueStatementLabel(SharedBox<'a, TraversableLabelIdentifier<'a>>), + BreakStatementLabel(SharedBox<'a, TraversableLabelIdentifier<'a>>), + ReturnStatementArgument(SharedBox<'a, TraversableExpression<'a>>), + WithStatementObject(SharedBox<'a, TraversableExpression<'a>>), + WithStatementBody(SharedBox<'a, TraversableStatement<'a>>), + SwitchStatementDiscriminant(SharedBox<'a, TraversableExpression<'a>>), + SwitchStatementCases(SharedBox<'a, TraversableSwitchCase<'a>>), + SwitchCaseTest(SharedBox<'a, TraversableExpression<'a>>), + SwitchCaseConsequent(SharedBox<'a, TraversableStatement<'a>>), + LabeledStatementLabel(SharedBox<'a, TraversableLabelIdentifier<'a>>), + LabeledStatementBody(SharedBox<'a, TraversableStatement<'a>>), + ThrowStatementArgument(SharedBox<'a, TraversableExpression<'a>>), + TryStatementBlock(SharedBox<'a, TraversableBlockStatement<'a>>), + TryStatementHandler(SharedBox<'a, TraversableCatchClause<'a>>), + TryStatementFinalizer(SharedBox<'a, TraversableBlockStatement<'a>>), + CatchClauseParam(SharedBox<'a, TraversableCatchParameter<'a>>), + CatchClauseBody(SharedBox<'a, TraversableBlockStatement<'a>>), + CatchParameterPattern(SharedBox<'a, TraversableBindingPattern<'a>>), + BindingPatternKind(SharedBox<'a, TraversableBindingPatternKind<'a>>), + BindingPatternTypeAnnotation(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + AssignmentPatternLeft(SharedBox<'a, TraversableBindingPattern<'a>>), + AssignmentPatternRight(SharedBox<'a, TraversableExpression<'a>>), + ObjectPatternProperties(SharedBox<'a, TraversableBindingProperty<'a>>), + ObjectPatternRest(SharedBox<'a, TraversableBindingRestElement<'a>>), + BindingPropertyKey(SharedBox<'a, TraversablePropertyKey<'a>>), + BindingPropertyValue(SharedBox<'a, TraversableBindingPattern<'a>>), + ArrayPatternElements(SharedBox<'a, TraversableBindingPattern<'a>>), + ArrayPatternRest(SharedBox<'a, TraversableBindingRestElement<'a>>), + BindingRestElementArgument(SharedBox<'a, TraversableBindingPattern<'a>>), + FunctionId(SharedBox<'a, TraversableBindingIdentifier<'a>>), + FunctionThisParam(SharedBox<'a, TraversableTSThisParameter<'a>>), + FunctionParams(SharedBox<'a, TraversableFormalParameters<'a>>), + FunctionBody(SharedBox<'a, TraversableFunctionBody<'a>>), + FunctionTypeParameters(SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>), + FunctionReturnType(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + FormalParametersItems(SharedBox<'a, TraversableFormalParameter<'a>>), + FormalParametersRest(SharedBox<'a, TraversableBindingRestElement<'a>>), + FormalParameterPattern(SharedBox<'a, TraversableBindingPattern<'a>>), + FormalParameterDecorators(SharedBox<'a, TraversableDecorator<'a>>), + FunctionBodyDirectives(SharedBox<'a, TraversableDirective<'a>>), + FunctionBodyStatements(SharedBox<'a, TraversableStatement<'a>>), + ArrowFunctionExpressionParams(SharedBox<'a, TraversableFormalParameters<'a>>), + ArrowFunctionExpressionBody(SharedBox<'a, TraversableFunctionBody<'a>>), + ArrowFunctionExpressionTypeParameters(SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>), + ArrowFunctionExpressionReturnType(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + YieldExpressionArgument(SharedBox<'a, TraversableExpression<'a>>), + ClassId(SharedBox<'a, TraversableBindingIdentifier<'a>>), + ClassSuperClass(SharedBox<'a, TraversableExpression<'a>>), + ClassBody(SharedBox<'a, TraversableClassBody<'a>>), + ClassTypeParameters(SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>), + ClassSuperTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + ClassImplements(SharedBox<'a, TraversableTSClassImplements<'a>>), + ClassDecorators(SharedBox<'a, TraversableDecorator<'a>>), + ClassBodyBody(SharedBox<'a, TraversableClassElement<'a>>), + MethodDefinitionKey(SharedBox<'a, TraversablePropertyKey<'a>>), + MethodDefinitionValue(SharedBox<'a, TraversableFunction<'a>>), + MethodDefinitionDecorators(SharedBox<'a, TraversableDecorator<'a>>), + PropertyDefinitionKey(SharedBox<'a, TraversablePropertyKey<'a>>), + PropertyDefinitionValue(SharedBox<'a, TraversableExpression<'a>>), + PropertyDefinitionTypeAnnotation(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + PropertyDefinitionDecorators(SharedBox<'a, TraversableDecorator<'a>>), + StaticBlockBody(SharedBox<'a, TraversableStatement<'a>>), + AccessorPropertyKey(SharedBox<'a, TraversablePropertyKey<'a>>), + AccessorPropertyValue(SharedBox<'a, TraversableExpression<'a>>), + AccessorPropertyDecorators(SharedBox<'a, TraversableDecorator<'a>>), + ImportExpressionSource(SharedBox<'a, TraversableExpression<'a>>), + ImportExpressionArguments(SharedBox<'a, TraversableExpression<'a>>), + ImportDeclarationSpecifiers(SharedBox<'a, TraversableImportDeclarationSpecifier<'a>>), + ImportDeclarationSource(SharedBox<'a, TraversableStringLiteral<'a>>), + ImportDeclarationWithClause(SharedBox<'a, TraversableWithClause<'a>>), + ImportSpecifierImported(SharedBox<'a, TraversableModuleExportName<'a>>), + ImportSpecifierLocal(SharedBox<'a, TraversableBindingIdentifier<'a>>), + ImportDefaultSpecifierLocal(SharedBox<'a, TraversableBindingIdentifier<'a>>), + ImportNamespaceSpecifierLocal(SharedBox<'a, TraversableBindingIdentifier<'a>>), + WithClauseWithEntries(SharedBox<'a, TraversableImportAttribute<'a>>), + ImportAttributeKey(SharedBox<'a, TraversableImportAttributeKey<'a>>), + ImportAttributeValue(SharedBox<'a, TraversableStringLiteral<'a>>), + ExportNamedDeclarationDeclaration(SharedBox<'a, TraversableDeclaration<'a>>), + ExportNamedDeclarationSpecifiers(SharedBox<'a, TraversableExportSpecifier<'a>>), + ExportNamedDeclarationSource(SharedBox<'a, TraversableStringLiteral<'a>>), + ExportNamedDeclarationWithClause(SharedBox<'a, TraversableWithClause<'a>>), + ExportDefaultDeclarationDeclaration(SharedBox<'a, TraversableExportDefaultDeclarationKind<'a>>), + ExportDefaultDeclarationExported(SharedBox<'a, TraversableModuleExportName<'a>>), + ExportAllDeclarationExported(SharedBox<'a, TraversableModuleExportName<'a>>), + ExportAllDeclarationSource(SharedBox<'a, TraversableStringLiteral<'a>>), + ExportAllDeclarationWithClause(SharedBox<'a, TraversableWithClause<'a>>), + ExportSpecifierLocal(SharedBox<'a, TraversableModuleExportName<'a>>), + ExportSpecifierExported(SharedBox<'a, TraversableModuleExportName<'a>>), + JSXElementOpeningElement(SharedBox<'a, TraversableJSXOpeningElement<'a>>), + JSXElementClosingElement(SharedBox<'a, TraversableJSXClosingElement<'a>>), + JSXElementChildren(SharedBox<'a, TraversableJSXChild<'a>>), + JSXOpeningElementName(SharedBox<'a, TraversableJSXElementName<'a>>), + JSXOpeningElementAttributes(SharedBox<'a, TraversableJSXAttributeItem<'a>>), + JSXOpeningElementTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + JSXClosingElementName(SharedBox<'a, TraversableJSXElementName<'a>>), + JSXFragmentChildren(SharedBox<'a, TraversableJSXChild<'a>>), + JSXNamespacedNameNamespace(SharedBox<'a, TraversableJSXIdentifier<'a>>), + JSXNamespacedNameProperty(SharedBox<'a, TraversableJSXIdentifier<'a>>), + JSXMemberExpressionObject(SharedBox<'a, TraversableJSXMemberExpressionObject<'a>>), + JSXMemberExpressionProperty(SharedBox<'a, TraversableJSXIdentifier<'a>>), + JSXExpressionContainerExpression(SharedBox<'a, TraversableJSXExpression<'a>>), + JSXAttributeName(SharedBox<'a, TraversableJSXAttributeName<'a>>), + JSXAttributeValue(SharedBox<'a, TraversableJSXAttributeValue<'a>>), + JSXSpreadAttributeArgument(SharedBox<'a, TraversableExpression<'a>>), + JSXSpreadChildExpression(SharedBox<'a, TraversableExpression<'a>>), + TSThisParameterTypeAnnotation(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSEnumDeclarationId(SharedBox<'a, TraversableBindingIdentifier<'a>>), + TSEnumDeclarationMembers(SharedBox<'a, TraversableTSEnumMember<'a>>), + TSEnumMemberId(SharedBox<'a, TraversableTSEnumMemberName<'a>>), + TSEnumMemberInitializer(SharedBox<'a, TraversableExpression<'a>>), + TSTypeAnnotationTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSLiteralTypeLiteral(SharedBox<'a, TraversableTSLiteral<'a>>), + TSConditionalTypeCheckType(SharedBox<'a, TraversableTSType<'a>>), + TSConditionalTypeExtendsType(SharedBox<'a, TraversableTSType<'a>>), + TSConditionalTypeTrueType(SharedBox<'a, TraversableTSType<'a>>), + TSConditionalTypeFalseType(SharedBox<'a, TraversableTSType<'a>>), + TSUnionTypeTypes(SharedBox<'a, TraversableTSType<'a>>), + TSIntersectionTypeTypes(SharedBox<'a, TraversableTSType<'a>>), + TSTypeOperatorTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSArrayTypeElementType(SharedBox<'a, TraversableTSType<'a>>), + TSIndexedAccessTypeObjectType(SharedBox<'a, TraversableTSType<'a>>), + TSIndexedAccessTypeIndexType(SharedBox<'a, TraversableTSType<'a>>), + TSTupleTypeElementTypes(SharedBox<'a, TraversableTSTupleElement<'a>>), + TSNamedTupleMemberElementType(SharedBox<'a, TraversableTSType<'a>>), + TSOptionalTypeTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSRestTypeTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSTypeReferenceTypeName(SharedBox<'a, TraversableTSTypeName<'a>>), + TSTypeReferenceTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + TSQualifiedNameLeft(SharedBox<'a, TraversableTSTypeName<'a>>), + TSTypeParameterInstantiationParams(SharedBox<'a, TraversableTSType<'a>>), + TSTypeParameterName(SharedBox<'a, TraversableBindingIdentifier<'a>>), + TSTypeParameterConstraint(SharedBox<'a, TraversableTSType<'a>>), + TSTypeParameterDefault(SharedBox<'a, TraversableTSType<'a>>), + TSTypeParameterDeclarationParams(SharedBox<'a, TraversableTSTypeParameter<'a>>), + TSTypeAliasDeclarationId(SharedBox<'a, TraversableBindingIdentifier<'a>>), + TSTypeAliasDeclarationTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSTypeAliasDeclarationTypeParameters(SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>), + TSClassImplementsExpression(SharedBox<'a, TraversableTSTypeName<'a>>), + TSClassImplementsTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + TSInterfaceDeclarationId(SharedBox<'a, TraversableBindingIdentifier<'a>>), + TSInterfaceDeclarationBody(SharedBox<'a, TraversableTSInterfaceBody<'a>>), + TSInterfaceDeclarationTypeParameters(SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>), + TSInterfaceDeclarationExtends(SharedBox<'a, TraversableTSInterfaceHeritage<'a>>), + TSInterfaceBodyBody(SharedBox<'a, TraversableTSSignature<'a>>), + TSPropertySignatureKey(SharedBox<'a, TraversablePropertyKey<'a>>), + TSPropertySignatureTypeAnnotation(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSIndexSignatureParameters(SharedBox<'a, TraversableTSIndexSignatureName<'a>>), + TSIndexSignatureTypeAnnotation(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSCallSignatureDeclarationThisParam(SharedBox<'a, TraversableTSThisParameter<'a>>), + TSCallSignatureDeclarationParams(SharedBox<'a, TraversableFormalParameters<'a>>), + TSCallSignatureDeclarationReturnType(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSCallSignatureDeclarationTypeParameters( + SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>, + ), + TSMethodSignatureKey(SharedBox<'a, TraversablePropertyKey<'a>>), + TSMethodSignatureThisParam(SharedBox<'a, TraversableTSThisParameter<'a>>), + TSMethodSignatureParams(SharedBox<'a, TraversableFormalParameters<'a>>), + TSMethodSignatureReturnType(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSMethodSignatureTypeParameters(SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>), + TSConstructSignatureDeclarationParams(SharedBox<'a, TraversableFormalParameters<'a>>), + TSConstructSignatureDeclarationReturnType(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSConstructSignatureDeclarationTypeParameters( + SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>, + ), + TSIndexSignatureNameTypeAnnotation(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSInterfaceHeritageExpression(SharedBox<'a, TraversableExpression<'a>>), + TSInterfaceHeritageTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + TSTypePredicateParameterName(SharedBox<'a, TraversableTSTypePredicateName<'a>>), + TSTypePredicateTypeAnnotation(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSModuleDeclarationId(SharedBox<'a, TraversableTSModuleDeclarationName<'a>>), + TSModuleDeclarationBody(SharedBox<'a, TraversableTSModuleDeclarationBody<'a>>), + TSModuleBlockBody(SharedBox<'a, TraversableStatement<'a>>), + TSTypeLiteralMembers(SharedBox<'a, TraversableTSSignature<'a>>), + TSInferTypeTypeParameter(SharedBox<'a, TraversableTSTypeParameter<'a>>), + TSTypeQueryExprName(SharedBox<'a, TraversableTSTypeQueryExprName<'a>>), + TSTypeQueryTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + TSImportTypeArgument(SharedBox<'a, TraversableTSType<'a>>), + TSImportTypeQualifier(SharedBox<'a, TraversableTSTypeName<'a>>), + TSImportTypeAttributes(SharedBox<'a, TraversableTSImportAttributes<'a>>), + TSImportTypeTypeParameters(SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>), + TSImportAttributesElements(SharedBox<'a, TraversableTSImportAttribute<'a>>), + TSImportAttributeName(SharedBox<'a, TraversableTSImportAttributeName<'a>>), + TSImportAttributeValue(SharedBox<'a, TraversableExpression<'a>>), + TSFunctionTypeThisParam(SharedBox<'a, TraversableTSThisParameter<'a>>), + TSFunctionTypeParams(SharedBox<'a, TraversableFormalParameters<'a>>), + TSFunctionTypeReturnType(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSFunctionTypeTypeParameters(SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>), + TSConstructorTypeParams(SharedBox<'a, TraversableFormalParameters<'a>>), + TSConstructorTypeReturnType(SharedBox<'a, TraversableTSTypeAnnotation<'a>>), + TSConstructorTypeTypeParameters(SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>), + TSMappedTypeTypeParameter(SharedBox<'a, TraversableTSTypeParameter<'a>>), + TSMappedTypeNameType(SharedBox<'a, TraversableTSType<'a>>), + TSMappedTypeTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSTemplateLiteralTypeQuasis(SharedBox<'a, TraversableTemplateElement<'a>>), + TSTemplateLiteralTypeTypes(SharedBox<'a, TraversableTSType<'a>>), + TSAsExpressionExpression(SharedBox<'a, TraversableExpression<'a>>), + TSAsExpressionTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSSatisfiesExpressionExpression(SharedBox<'a, TraversableExpression<'a>>), + TSSatisfiesExpressionTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSTypeAssertionExpression(SharedBox<'a, TraversableExpression<'a>>), + TSTypeAssertionTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), + TSImportEqualsDeclarationId(SharedBox<'a, TraversableBindingIdentifier<'a>>), + TSImportEqualsDeclarationModuleReference(SharedBox<'a, TraversableTSModuleReference<'a>>), + TSExternalModuleReferenceExpression(SharedBox<'a, TraversableStringLiteral<'a>>), + TSNonNullExpressionExpression(SharedBox<'a, TraversableExpression<'a>>), + DecoratorExpression(SharedBox<'a, TraversableExpression<'a>>), + TSExportAssignmentExpression(SharedBox<'a, TraversableExpression<'a>>), + TSInstantiationExpressionExpression(SharedBox<'a, TraversableExpression<'a>>), + TSInstantiationExpressionTypeParameters( + SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>, + ), + JSDocNullableTypeTypeAnnotation(SharedBox<'a, TraversableTSType<'a>>), +} diff --git a/crates/oxc_ast/src/traverse/ast.rs b/crates/oxc_ast/src/traverse/ast.rs new file mode 100644 index 0000000000000..cfe707777a5b3 --- /dev/null +++ b/crates/oxc_ast/src/traverse/ast.rs @@ -0,0 +1,239 @@ +#![allow(dead_code)] // just for now +#![allow(unused_imports)] +use crate::ast; +use oxc_allocator::Allocator; + +/// AST builder for creating AST nodes for traversable AST +pub struct TraversableAstBuilder<'a> { + pub allocator: &'a Allocator, +} + +impl<'a> TraversableAstBuilder<'a> { + pub fn new(allocator: &'a Allocator) -> Self { + Self { allocator } + } +} + +pub use ast::traversable_accessorproperty::*; +pub use ast::traversable_argument::*; +pub use ast::traversable_arrayassignmenttarget::*; +pub use ast::traversable_arrayexpression::*; +pub use ast::traversable_arrayexpressionelement::*; +pub use ast::traversable_arraypattern::*; +pub use ast::traversable_arrowfunctionexpression::*; +pub use ast::traversable_assignmentexpression::*; +pub use ast::traversable_assignmentpattern::*; +pub use ast::traversable_assignmenttarget::*; +pub use ast::traversable_assignmenttargetmaybedefault::*; +pub use ast::traversable_assignmenttargetpattern::*; +pub use ast::traversable_assignmenttargetproperty::*; +pub use ast::traversable_assignmenttargetpropertyidentifier::*; +pub use ast::traversable_assignmenttargetpropertyproperty::*; +pub use ast::traversable_assignmenttargetrest::*; +pub use ast::traversable_assignmenttargetwithdefault::*; +pub use ast::traversable_awaitexpression::*; +pub use ast::traversable_bigintliteral::*; +pub use ast::traversable_binaryexpression::*; +pub use ast::traversable_bindingidentifier::*; +pub use ast::traversable_bindingpattern::*; +pub use ast::traversable_bindingpatternkind::*; +pub use ast::traversable_bindingproperty::*; +pub use ast::traversable_bindingrestelement::*; +pub use ast::traversable_blockstatement::*; +pub use ast::traversable_booleanliteral::*; +pub use ast::traversable_breakstatement::*; +pub use ast::traversable_callexpression::*; +pub use ast::traversable_catchclause::*; +pub use ast::traversable_catchparameter::*; +pub use ast::traversable_chainelement::*; +pub use ast::traversable_chainexpression::*; +pub use ast::traversable_class::*; +pub use ast::traversable_classbody::*; +pub use ast::traversable_classelement::*; +pub use ast::traversable_computedmemberexpression::*; +pub use ast::traversable_conditionalexpression::*; +pub use ast::traversable_continuestatement::*; +pub use ast::traversable_debuggerstatement::*; +pub use ast::traversable_declaration::*; +pub use ast::traversable_decorator::*; +pub use ast::traversable_directive::*; +pub use ast::traversable_dowhilestatement::*; +pub use ast::traversable_elision::*; +pub use ast::traversable_emptystatement::*; +pub use ast::traversable_exportalldeclaration::*; +pub use ast::traversable_exportdefaultdeclaration::*; +pub use ast::traversable_exportdefaultdeclarationkind::*; +pub use ast::traversable_exportnameddeclaration::*; +pub use ast::traversable_exportspecifier::*; +pub use ast::traversable_expression::*; +pub use ast::traversable_expressionstatement::*; +pub use ast::traversable_forinstatement::*; +pub use ast::traversable_formalparameter::*; +pub use ast::traversable_formalparameters::*; +pub use ast::traversable_forofstatement::*; +pub use ast::traversable_forstatement::*; +pub use ast::traversable_forstatementinit::*; +pub use ast::traversable_forstatementleft::*; +pub use ast::traversable_function::*; +pub use ast::traversable_functionbody::*; +pub use ast::traversable_hashbang::*; +pub use ast::traversable_identifierreference::*; +pub use ast::traversable_ifstatement::*; +pub use ast::traversable_importattribute::*; +pub use ast::traversable_importattributekey::*; +pub use ast::traversable_importdeclaration::*; +pub use ast::traversable_importdeclarationspecifier::*; +pub use ast::traversable_importdefaultspecifier::*; +pub use ast::traversable_importexpression::*; +pub use ast::traversable_importnamespacespecifier::*; +pub use ast::traversable_importspecifier::*; +pub use ast::traversable_jsdocnullabletype::*; +pub use ast::traversable_jsdocunknowntype::*; +pub use ast::traversable_jsxattribute::*; +pub use ast::traversable_jsxattributeitem::*; +pub use ast::traversable_jsxattributename::*; +pub use ast::traversable_jsxattributevalue::*; +pub use ast::traversable_jsxchild::*; +pub use ast::traversable_jsxclosingelement::*; +pub use ast::traversable_jsxelement::*; +pub use ast::traversable_jsxelementname::*; +pub use ast::traversable_jsxemptyexpression::*; +pub use ast::traversable_jsxexpression::*; +pub use ast::traversable_jsxexpressioncontainer::*; +pub use ast::traversable_jsxfragment::*; +pub use ast::traversable_jsxidentifier::*; +pub use ast::traversable_jsxmemberexpression::*; +pub use ast::traversable_jsxmemberexpressionobject::*; +pub use ast::traversable_jsxnamespacedname::*; +pub use ast::traversable_jsxopeningelement::*; +pub use ast::traversable_jsxspreadattribute::*; +pub use ast::traversable_jsxspreadchild::*; +pub use ast::traversable_jsxtext::*; +pub use ast::traversable_labeledstatement::*; +pub use ast::traversable_labelidentifier::*; +pub use ast::traversable_logicalexpression::*; +pub use ast::traversable_memberexpression::*; +pub use ast::traversable_metaproperty::*; +pub use ast::traversable_methoddefinition::*; +pub use ast::traversable_moduledeclaration::*; +pub use ast::traversable_moduleexportname::*; +pub use ast::traversable_newexpression::*; +pub use ast::traversable_nullliteral::*; +pub use ast::traversable_numericliteral::*; +pub use ast::traversable_objectassignmenttarget::*; +pub use ast::traversable_objectexpression::*; +pub use ast::traversable_objectpattern::*; +pub use ast::traversable_objectproperty::*; +pub use ast::traversable_objectpropertykind::*; +pub use ast::traversable_parenthesizedexpression::*; +pub use ast::traversable_privatefieldexpression::*; +pub use ast::traversable_privateidentifier::*; +pub use ast::traversable_privateinexpression::*; +pub use ast::traversable_program::*; +pub use ast::traversable_propertydefinition::*; +pub use ast::traversable_propertykey::*; +pub use ast::traversable_regexpliteral::*; +pub use ast::traversable_returnstatement::*; +pub use ast::traversable_sequenceexpression::*; +pub use ast::traversable_simpleassignmenttarget::*; +pub use ast::traversable_spreadelement::*; +pub use ast::traversable_statement::*; +pub use ast::traversable_staticblock::*; +pub use ast::traversable_staticmemberexpression::*; +pub use ast::traversable_stringliteral::*; +pub use ast::traversable_super::*; +pub use ast::traversable_switchcase::*; +pub use ast::traversable_switchstatement::*; +pub use ast::traversable_taggedtemplateexpression::*; +pub use ast::traversable_templateelement::*; +pub use ast::traversable_templateliteral::*; +pub use ast::traversable_thisexpression::*; +pub use ast::traversable_throwstatement::*; +pub use ast::traversable_trystatement::*; +pub use ast::traversable_tsanykeyword::*; +pub use ast::traversable_tsarraytype::*; +pub use ast::traversable_tsasexpression::*; +pub use ast::traversable_tsbigintkeyword::*; +pub use ast::traversable_tsbooleankeyword::*; +pub use ast::traversable_tscallsignaturedeclaration::*; +pub use ast::traversable_tsclassimplements::*; +pub use ast::traversable_tsconditionaltype::*; +pub use ast::traversable_tsconstructortype::*; +pub use ast::traversable_tsconstructsignaturedeclaration::*; +pub use ast::traversable_tsenumdeclaration::*; +pub use ast::traversable_tsenummember::*; +pub use ast::traversable_tsenummembername::*; +pub use ast::traversable_tsexportassignment::*; +pub use ast::traversable_tsexternalmodulereference::*; +pub use ast::traversable_tsfunctiontype::*; +pub use ast::traversable_tsimportattribute::*; +pub use ast::traversable_tsimportattributename::*; +pub use ast::traversable_tsimportattributes::*; +pub use ast::traversable_tsimportequalsdeclaration::*; +pub use ast::traversable_tsimporttype::*; +pub use ast::traversable_tsindexedaccesstype::*; +pub use ast::traversable_tsindexsignature::*; +pub use ast::traversable_tsindexsignaturename::*; +pub use ast::traversable_tsinfertype::*; +pub use ast::traversable_tsinstantiationexpression::*; +pub use ast::traversable_tsinterfacebody::*; +pub use ast::traversable_tsinterfacedeclaration::*; +pub use ast::traversable_tsinterfaceheritage::*; +pub use ast::traversable_tsintersectiontype::*; +pub use ast::traversable_tsliteral::*; +pub use ast::traversable_tsliteraltype::*; +pub use ast::traversable_tsmappedtype::*; +pub use ast::traversable_tsmethodsignature::*; +pub use ast::traversable_tsmoduleblock::*; +pub use ast::traversable_tsmoduledeclaration::*; +pub use ast::traversable_tsmoduledeclarationbody::*; +pub use ast::traversable_tsmoduledeclarationname::*; +pub use ast::traversable_tsmodulereference::*; +pub use ast::traversable_tsnamedtuplemember::*; +pub use ast::traversable_tsnamespaceexportdeclaration::*; +pub use ast::traversable_tsneverkeyword::*; +pub use ast::traversable_tsnonnullexpression::*; +pub use ast::traversable_tsnullkeyword::*; +pub use ast::traversable_tsnumberkeyword::*; +pub use ast::traversable_tsobjectkeyword::*; +pub use ast::traversable_tsoptionaltype::*; +pub use ast::traversable_tspropertysignature::*; +pub use ast::traversable_tsqualifiedname::*; +pub use ast::traversable_tsresttype::*; +pub use ast::traversable_tssatisfiesexpression::*; +pub use ast::traversable_tssignature::*; +pub use ast::traversable_tsstringkeyword::*; +pub use ast::traversable_tssymbolkeyword::*; +pub use ast::traversable_tstemplateliteraltype::*; +pub use ast::traversable_tsthisparameter::*; +pub use ast::traversable_tsthistype::*; +pub use ast::traversable_tstupleelement::*; +pub use ast::traversable_tstupletype::*; +pub use ast::traversable_tstype::*; +pub use ast::traversable_tstypealiasdeclaration::*; +pub use ast::traversable_tstypeannotation::*; +pub use ast::traversable_tstypeassertion::*; +pub use ast::traversable_tstypeliteral::*; +pub use ast::traversable_tstypename::*; +pub use ast::traversable_tstypeoperator::*; +pub use ast::traversable_tstypeparameter::*; +pub use ast::traversable_tstypeparameterdeclaration::*; +pub use ast::traversable_tstypeparameterinstantiation::*; +pub use ast::traversable_tstypepredicate::*; +pub use ast::traversable_tstypepredicatename::*; +pub use ast::traversable_tstypequery::*; +pub use ast::traversable_tstypequeryexprname::*; +pub use ast::traversable_tstypereference::*; +pub use ast::traversable_tsundefinedkeyword::*; +pub use ast::traversable_tsuniontype::*; +pub use ast::traversable_tsunknownkeyword::*; +pub use ast::traversable_tsvoidkeyword::*; +pub use ast::traversable_unaryexpression::*; +pub use ast::traversable_updateexpression::*; +pub use ast::traversable_usingdeclaration::*; +pub use ast::traversable_variabledeclaration::*; +pub use ast::traversable_variabledeclarator::*; +pub use ast::traversable_whilestatement::*; +pub use ast::traversable_withclause::*; +pub use ast::traversable_withstatement::*; +pub use ast::traversable_yieldexpression::*; diff --git a/crates/oxc_ast/src/traverse/ast_builder.rs b/crates/oxc_ast/src/traverse/ast_builder.rs new file mode 100644 index 0000000000000..6eac285ac7daf --- /dev/null +++ b/crates/oxc_ast/src/traverse/ast_builder.rs @@ -0,0 +1,20 @@ +use oxc_allocator::Allocator; + +use super::{cell::GCell, SharedBox}; + +/// AST builder for creating AST nodes for traversable AST. +// Further methods are added by `#[ast_node]` macro. +pub struct AstBuilder<'a> { + pub allocator: &'a Allocator, +} + +impl<'a> AstBuilder<'a> { + pub fn new(allocator: &'a Allocator) -> Self { + Self { allocator } + } + + #[inline] + pub fn alloc(&self, node: T) -> SharedBox<'a, T> { + GCell::from_mut(self.allocator.alloc(node)) + } +} diff --git a/crates/oxc_ast/src/traverse/cell.rs b/crates/oxc_ast/src/traverse/cell.rs new file mode 100644 index 0000000000000..ce86d91c08026 --- /dev/null +++ b/crates/oxc_ast/src/traverse/cell.rs @@ -0,0 +1,190 @@ +#![allow(dead_code)] // just for now +//! Cell type and token for traversing AST. +//! +//! Based on `GhostCell`. +//! All method implementations copied verbatim from original version by paper's authors +//! +//! and `ghost_cell` crate ``. +//! +//! Only difference is that instead of using a lifetime to constrain the life of access tokens, +//! here we provide only an unsafe method `Token::new_unchecked` and the user must maintain +//! the invariant that only one token may be "in play" at same time +//! (see below for exactly what "in play" means). +//! +//! This alteration removes a lifetime, and avoids the unergonomic pattern of all the code that +//! works with a structure containing `GCell`s needing to be within a single closure. + +use std::cell::UnsafeCell; + +use oxc_allocator::Allocator; + +/// Access token for traversing AST. +#[repr(transparent)] +pub struct Token(()); + +impl Token { + /// Create new access token for traversing AST. + /// + /// It is imperative that any code operating on a single AST does not have access to more + /// than 1 token. `GCell` uses this guarantee to make it impossible to obtain a `&mut` + /// reference to any AST node while another reference exists. If more than 1 token is "in play", + /// this guarantee can be broken, and may lead to undefined behavior. + /// + /// This function is used internally by `transform`, but probably should not be used elsewhere. + /// + /// It is permissable to create multiple tokens which are never used together on the same AST. + /// In practice, this means it is possible to transform multiple ASTs on different threads + /// simultaneously. + /// + /// If operating on multiple ASTs together (e.g. concatenating 2 files), then a single token + /// must be used to access all the ASTs involved in the operation NOT 1 token per AST. + /// + /// # SAFETY + /// Caller must ensure only a single token is used with any AST at one time. + #[inline] + #[allow(unsafe_code)] + pub unsafe fn new_unchecked() -> Self { + Self(()) + } +} + +/// A cell type providing interior mutability, with aliasing rules enforced at compile time. +#[repr(transparent)] +pub struct GCell { + value: UnsafeCell, +} + +#[allow(dead_code)] +impl GCell { + pub const fn new(value: T) -> Self { + GCell { value: UnsafeCell::new(value) } + } + + pub fn into_inner(self) -> T { + self.value.into_inner() + } +} + +#[allow(dead_code, unused_variables)] +impl GCell { + #[inline] + #[allow(unsafe_code)] + pub fn borrow<'a>(&'a self, tk: &'a Token) -> &'a T { + // SAFETY: At any time there is only a single token for each AST. + unsafe { &*self.value.get() } + } + + #[inline] + #[allow(unsafe_code)] + pub fn borrow_mut<'a>(&'a self, tk: &'a mut Token) -> &'a mut T { + // SAFETY: At any time there is only a single token for each AST. + unsafe { &mut *self.value.get() } + } + + #[inline] + pub const fn as_ptr(&self) -> *mut T { + self.value.get() + } + + #[inline] + #[allow(unsafe_code)] + pub fn get_mut(&mut self) -> &mut T { + // SAFETY: We have an exclusive mutable access to the cell. + unsafe { &mut *self.value.get() } + } + + #[inline] + #[allow(unsafe_code)] + pub fn from_mut(t: &mut T) -> &mut Self { + // TODO: @overlookmotel make sure this safety documentation is correct. + // SAFETY: A `GCell` always have the same alignment as its inner value, + // It is only a compile-time abstraction, So we can safely transmute between them. + unsafe { &mut *(t as *mut T as *mut Self) } + } +} + +#[allow(dead_code)] +impl GCell<[T]> { + #[inline] + #[allow(unsafe_code)] + pub fn as_slice_of_cells(&self) -> &[GCell] { + // TODO: @overlookmotel make sure this safety documentation is correct. + // SAFETY: A `GCell` always have the same alignment as its inner value, + // It is only a compile-time abstraction, So we can safely transmute between them. + // There is no difference between slice of `GCell`s and `GCell` of slice. + unsafe { &*(self as *const GCell<[T]> as *const [GCell]) } + } +} + +#[allow(dead_code)] +impl GCell { + #[inline] + pub fn replace(&self, value: T, tk: &mut Token) -> T { + std::mem::replace(self.borrow_mut(tk), value) + } + + #[inline] + pub fn take(&self, tk: &mut Token) -> T + where + T: Default, + { + self.replace(T::default(), tk) + } +} + +#[allow(dead_code)] +impl GCell { + #[inline] + pub fn clone(&self, tk: &Token) -> Self { + GCell::new(self.borrow(tk).clone()) + } +} + +impl Default for GCell { + #[inline] + fn default() -> Self { + Self::new(T::default()) + } +} + +impl AsMut for GCell { + #[inline] + fn as_mut(&mut self) -> &mut T { + self.get_mut() + } +} + +impl From for GCell { + fn from(t: T) -> Self { + GCell::new(t) + } +} + +#[allow(unsafe_code)] +// SAFETY: `GhostCell` is `Send` + `Sync`, so `GCell` can be too +unsafe impl Send for GCell {} + +#[allow(unsafe_code)] +// SAFETY: `GhostCell` is `Send` + `Sync`, so `GCell` can be too +unsafe impl Sync for GCell {} + +/// Type alias for a shared ref to a `GCell`. +/// This is the interior-mutable equivalent to `oxc_allocator::Box`. +pub type SharedBox<'a, T> = &'a GCell; + +/// Type alias for a shared Vec +pub type SharedVec<'a, T> = oxc_allocator::Vec<'a, GCell>; + +/// Trait to sugar `GCell::from_mut(allocator.alloc(t))` to `allocator.galloc(t)`. +trait GCellAlloc { + #[allow(clippy::mut_from_ref)] + fn galloc(&self, value: T) -> &mut GCell; +} + +impl GCellAlloc for Allocator { + /// Allocate `T` into arena and return a `&mut GCell` to it + #[inline] + fn galloc(&self, value: T) -> &mut GCell { + GCell::from_mut(self.alloc(value)) + } +} diff --git a/crates/oxc_ast/src/traverse/mod.rs b/crates/oxc_ast/src/traverse/mod.rs new file mode 100644 index 0000000000000..4d249405f929f --- /dev/null +++ b/crates/oxc_ast/src/traverse/mod.rs @@ -0,0 +1,17 @@ +#![allow(unused_imports)] // TODO: Remove this attr once all type are in use + +mod ancestor; +pub mod ast; +mod ast_builder; +mod cell; +mod orphan; +mod transform; +#[allow(clippy::module_inception)] +mod traverse; + +pub use ancestor::Ancestor; +pub use ast_builder::AstBuilder; +pub use cell::{GCell, SharedBox, SharedVec, Token}; +pub use orphan::Orphan; +pub use transform::{transform, TraverseCtx}; +pub use traverse::Traverse; diff --git a/crates/oxc_ast/src/traverse/orphan.rs b/crates/oxc_ast/src/traverse/orphan.rs new file mode 100644 index 0000000000000..102bf90b0f026 --- /dev/null +++ b/crates/oxc_ast/src/traverse/orphan.rs @@ -0,0 +1,40 @@ +#![allow(dead_code)] // just for now +use std::ops::Deref; + +/// Wrapper for AST nodes which have been disconnected from the AST. +/// +/// This type is central to preventing a node from being attached to the AST in multiple places. +/// +/// `Orphan` cannot be `Copy` or `Clone`, or it would allow creating a duplicate ref to the +/// contained node. The original `Orphan` could be attached to the AST, and then the copy +/// could also be attached to the AST elsewhere. +#[repr(transparent)] +pub struct Orphan(T); + +impl Orphan { + /// Wrap node to indicate it's disconnected from AST. + /// SAFETY: Caller must ensure that `node` is not attached to the AST. + #[inline] + #[allow(unsafe_code)] + pub unsafe fn new(node: T) -> Self { + Self(node) + } + + /// Unwrap node from `Orphan`. + /// This should only be done before inserting it into the AST. + /// Not unsafe as there is nothing bad you can do with an un-orphaned AST node. + /// No APIs are provided to attach nodes to the AST, unless they're wrapped in `Orphan`. + #[inline] + pub fn inner(self) -> T { + self.0 + } +} + +impl Deref for Orphan { + type Target = T; + + #[inline] + fn deref(&self) -> &T { + &self.0 + } +} diff --git a/crates/oxc_ast/src/traverse/transform.rs b/crates/oxc_ast/src/traverse/transform.rs new file mode 100644 index 0000000000000..75ef0299c1ca0 --- /dev/null +++ b/crates/oxc_ast/src/traverse/transform.rs @@ -0,0 +1,104 @@ +#![allow(dead_code)] // TODO: Remove this attr once used in a transform + +use oxc_allocator::Allocator; + +use super::{ast::TraversableProgram, Ancestor, AstBuilder, GCell, SharedBox, Token, Traverse}; +use crate::ast::{traverse, Program as StandardProgram}; + +/// Run transform visitor on AST. +/// +/// The provided transformer must implement `Traverse` and will be run on a version of the AST +/// with interior mutability, allowing traversal in any direction (up or down). +/// Once the transform is finished, caller can continue to use the standard version of the AST +/// in the usual way, without interior mutability. +#[allow(unsafe_code)] +pub fn transform<'a, T: Traverse<'a>>( + transformer: &mut T, + program: &mut StandardProgram<'a>, + allocator: &'a Allocator, +) { + // Generate `Token` which transformer uses to access the AST. + // SAFETY: We only create one token, and it never leaves this function. + let mut token = unsafe { Token::new_unchecked() }; + + // Create `TraverseCtx` which transformer uses to read ancestry + let mut ctx = TraverseCtx::new(allocator); + + // Convert AST to traversable version. + // + // SAFETY: All standard and traversable AST types are mirrors of each other, with identical layouts. + // This is ensured by `#[repr(C)]` on all types. Therefore one can safely be transmuted to the other. + // As we hold a `&mut` reference to the AST, it's guaranteed there are no other live references. + // We extend the lifetime of ref to `TraversableProgram` to `&'a TraversableProgram`. + // This is safe because the node is in the arena, and doesn't move, so the ref is valid for `'a`. + // `transformer` could smuggle refs out, but could not use them without a token which is only + // available in this function. + // + // TODO: Refs could be made invalid if the allocator is reset. Hopefully this is impossible + // because `Allocator::reset` takes a `&mut` ref to the allocator, so you can't hold any immut refs + // to data in the arena at that time. But make sure. + #[allow(clippy::ptr_as_ptr, clippy::undocumented_unsafe_blocks)] + let program = GCell::from_mut(unsafe { &mut *(program as *mut _ as *mut TraversableProgram) }); + + // Run transformer on the traversable AST + traverse(transformer, program, &mut ctx, &mut token); + + // The access token goes out of scope at this point, which guarantees that no references + // (either mutable or immutable) to the traversable AST or the token still exist. + // If the transformer attempts to hold on to any references to the AST, or to the token, + // this will produce a compile-time error. + // Therefore, the caller can now safely continue using the `&mut Program` that they passed in. +} + +/// Traverse context. +/// +/// Passed to all AST visitor functions. +/// +/// Provides ability to: +/// * Query parent/ancestor of current node. +/// * Create AST nodes via `ctx.ast`. +/// * Allocate into arena via `ctx.alloc()`. +pub struct TraverseCtx<'a> { + stack: Vec>, + pub ast: AstBuilder<'a>, +} + +impl<'a> TraverseCtx<'a> { + pub fn new(allocator: &'a Allocator) -> Self { + Self { stack: Vec::new(), ast: AstBuilder::new(allocator) } + } + + #[allow(dead_code)] // TODO: Remove this attr once method is used in a transform + #[inline] + pub fn alloc(&self, node: T) -> SharedBox<'a, T> { + self.ast.alloc(node) + } +} + +impl<'a> TraverseCtx<'a> { + #[inline] + pub fn parent(&self) -> Ancestor<'a> { + *self.stack.last().unwrap() + } + + #[inline] + pub fn ancestor(&self, levels: usize) -> Option> { + self.stack.get(self.stack.len() - levels).copied() + } + + #[inline] + pub fn push_stack(&mut self, parent: Ancestor<'a>) { + self.stack.push(parent); + } + + #[inline] + pub fn pop_stack(&mut self) { + self.stack.pop(); + } + + #[inline] + pub fn replace_stack(&mut self, parent: Ancestor<'a>) { + let index = self.stack.len() - 1; + self.stack[index] = parent; + } +} diff --git a/crates/oxc_ast/src/traverse/traverse.rs b/crates/oxc_ast/src/traverse/traverse.rs new file mode 100644 index 0000000000000..4b9b9b8f52591 --- /dev/null +++ b/crates/oxc_ast/src/traverse/traverse.rs @@ -0,0 +1,3094 @@ +// Generated by `scripts/build.js`. + +use super::{ast::*, cell::Token, SharedBox, TraverseCtx}; + +#[allow(unused_variables)] +pub trait Traverse<'a> { + fn enter_program( + &mut self, + node: SharedBox<'a, TraversableProgram<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_program( + &mut self, + node: SharedBox<'a, TraversableProgram<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_expression( + &mut self, + node: TraversableExpression<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_expression( + &mut self, + node: TraversableExpression<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_identifier_reference( + &mut self, + node: SharedBox<'a, TraversableIdentifierReference<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_binding_identifier( + &mut self, + node: SharedBox<'a, TraversableBindingIdentifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_label_identifier( + &mut self, + node: SharedBox<'a, TraversableLabelIdentifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_this_expression( + &mut self, + node: SharedBox<'a, TraversableThisExpression>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_array_expression( + &mut self, + node: SharedBox<'a, TraversableArrayExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_array_expression( + &mut self, + node: SharedBox<'a, TraversableArrayExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_array_expression_element( + &mut self, + node: TraversableArrayExpressionElement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_array_expression_element( + &mut self, + node: TraversableArrayExpressionElement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_elision( + &mut self, + node: SharedBox<'a, TraversableElision>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_object_expression( + &mut self, + node: SharedBox<'a, TraversableObjectExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_object_expression( + &mut self, + node: SharedBox<'a, TraversableObjectExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_object_property_kind( + &mut self, + node: TraversableObjectPropertyKind<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_object_property_kind( + &mut self, + node: TraversableObjectPropertyKind<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_object_property( + &mut self, + node: SharedBox<'a, TraversableObjectProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_object_property( + &mut self, + node: SharedBox<'a, TraversableObjectProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_property_key( + &mut self, + node: TraversablePropertyKey<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_property_key( + &mut self, + node: TraversablePropertyKey<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_template_literal( + &mut self, + node: SharedBox<'a, TraversableTemplateLiteral<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_template_literal( + &mut self, + node: SharedBox<'a, TraversableTemplateLiteral<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_tagged_template_expression( + &mut self, + node: SharedBox<'a, TraversableTaggedTemplateExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_tagged_template_expression( + &mut self, + node: SharedBox<'a, TraversableTaggedTemplateExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_template_element( + &mut self, + node: SharedBox<'a, TraversableTemplateElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_member_expression( + &mut self, + node: TraversableMemberExpression<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_member_expression( + &mut self, + node: TraversableMemberExpression<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_computed_member_expression( + &mut self, + node: SharedBox<'a, TraversableComputedMemberExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_computed_member_expression( + &mut self, + node: SharedBox<'a, TraversableComputedMemberExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_static_member_expression( + &mut self, + node: SharedBox<'a, TraversableStaticMemberExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_static_member_expression( + &mut self, + node: SharedBox<'a, TraversableStaticMemberExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_private_field_expression( + &mut self, + node: SharedBox<'a, TraversablePrivateFieldExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_private_field_expression( + &mut self, + node: SharedBox<'a, TraversablePrivateFieldExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_call_expression( + &mut self, + node: SharedBox<'a, TraversableCallExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_call_expression( + &mut self, + node: SharedBox<'a, TraversableCallExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_new_expression( + &mut self, + node: SharedBox<'a, TraversableNewExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_new_expression( + &mut self, + node: SharedBox<'a, TraversableNewExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_meta_property( + &mut self, + node: SharedBox<'a, TraversableMetaProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_spread_element( + &mut self, + node: SharedBox<'a, TraversableSpreadElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_spread_element( + &mut self, + node: SharedBox<'a, TraversableSpreadElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_argument( + &mut self, + node: TraversableArgument<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_argument( + &mut self, + node: TraversableArgument<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_update_expression( + &mut self, + node: SharedBox<'a, TraversableUpdateExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_update_expression( + &mut self, + node: SharedBox<'a, TraversableUpdateExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_unary_expression( + &mut self, + node: SharedBox<'a, TraversableUnaryExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_unary_expression( + &mut self, + node: SharedBox<'a, TraversableUnaryExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_binary_expression( + &mut self, + node: SharedBox<'a, TraversableBinaryExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_binary_expression( + &mut self, + node: SharedBox<'a, TraversableBinaryExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_private_in_expression( + &mut self, + node: SharedBox<'a, TraversablePrivateInExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_private_in_expression( + &mut self, + node: SharedBox<'a, TraversablePrivateInExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_logical_expression( + &mut self, + node: SharedBox<'a, TraversableLogicalExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_logical_expression( + &mut self, + node: SharedBox<'a, TraversableLogicalExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_conditional_expression( + &mut self, + node: SharedBox<'a, TraversableConditionalExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_conditional_expression( + &mut self, + node: SharedBox<'a, TraversableConditionalExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_expression( + &mut self, + node: SharedBox<'a, TraversableAssignmentExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_expression( + &mut self, + node: SharedBox<'a, TraversableAssignmentExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_target( + &mut self, + node: TraversableAssignmentTarget<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_target( + &mut self, + node: TraversableAssignmentTarget<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_simple_assignment_target( + &mut self, + node: TraversableSimpleAssignmentTarget<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_simple_assignment_target( + &mut self, + node: TraversableSimpleAssignmentTarget<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_target_pattern( + &mut self, + node: TraversableAssignmentTargetPattern<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_target_pattern( + &mut self, + node: TraversableAssignmentTargetPattern<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_array_assignment_target( + &mut self, + node: SharedBox<'a, TraversableArrayAssignmentTarget<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_array_assignment_target( + &mut self, + node: SharedBox<'a, TraversableArrayAssignmentTarget<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_object_assignment_target( + &mut self, + node: SharedBox<'a, TraversableObjectAssignmentTarget<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_object_assignment_target( + &mut self, + node: SharedBox<'a, TraversableObjectAssignmentTarget<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_target_rest( + &mut self, + node: SharedBox<'a, TraversableAssignmentTargetRest<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_target_rest( + &mut self, + node: SharedBox<'a, TraversableAssignmentTargetRest<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_target_maybe_default( + &mut self, + node: TraversableAssignmentTargetMaybeDefault<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_target_maybe_default( + &mut self, + node: TraversableAssignmentTargetMaybeDefault<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_target_with_default( + &mut self, + node: SharedBox<'a, TraversableAssignmentTargetWithDefault<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_target_with_default( + &mut self, + node: SharedBox<'a, TraversableAssignmentTargetWithDefault<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_target_property( + &mut self, + node: TraversableAssignmentTargetProperty<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_target_property( + &mut self, + node: TraversableAssignmentTargetProperty<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_target_property_identifier( + &mut self, + node: SharedBox<'a, TraversableAssignmentTargetPropertyIdentifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_target_property_identifier( + &mut self, + node: SharedBox<'a, TraversableAssignmentTargetPropertyIdentifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_target_property_property( + &mut self, + node: SharedBox<'a, TraversableAssignmentTargetPropertyProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_target_property_property( + &mut self, + node: SharedBox<'a, TraversableAssignmentTargetPropertyProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_sequence_expression( + &mut self, + node: SharedBox<'a, TraversableSequenceExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_sequence_expression( + &mut self, + node: SharedBox<'a, TraversableSequenceExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_super( + &mut self, + node: SharedBox<'a, TraversableSuper>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_await_expression( + &mut self, + node: SharedBox<'a, TraversableAwaitExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_await_expression( + &mut self, + node: SharedBox<'a, TraversableAwaitExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_chain_expression( + &mut self, + node: SharedBox<'a, TraversableChainExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_chain_expression( + &mut self, + node: SharedBox<'a, TraversableChainExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_chain_element( + &mut self, + node: TraversableChainElement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_chain_element( + &mut self, + node: TraversableChainElement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_parenthesized_expression( + &mut self, + node: SharedBox<'a, TraversableParenthesizedExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_parenthesized_expression( + &mut self, + node: SharedBox<'a, TraversableParenthesizedExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_statement( + &mut self, + node: TraversableStatement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_statement( + &mut self, + node: TraversableStatement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_directive( + &mut self, + node: SharedBox<'a, TraversableDirective<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_directive( + &mut self, + node: SharedBox<'a, TraversableDirective<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_hashbang( + &mut self, + node: SharedBox<'a, TraversableHashbang<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_block_statement( + &mut self, + node: SharedBox<'a, TraversableBlockStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_block_statement( + &mut self, + node: SharedBox<'a, TraversableBlockStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_declaration( + &mut self, + node: TraversableDeclaration<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_declaration( + &mut self, + node: TraversableDeclaration<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_variable_declaration( + &mut self, + node: SharedBox<'a, TraversableVariableDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_variable_declaration( + &mut self, + node: SharedBox<'a, TraversableVariableDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_variable_declarator( + &mut self, + node: SharedBox<'a, TraversableVariableDeclarator<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_variable_declarator( + &mut self, + node: SharedBox<'a, TraversableVariableDeclarator<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_using_declaration( + &mut self, + node: SharedBox<'a, TraversableUsingDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_using_declaration( + &mut self, + node: SharedBox<'a, TraversableUsingDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_empty_statement( + &mut self, + node: SharedBox<'a, TraversableEmptyStatement>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_expression_statement( + &mut self, + node: SharedBox<'a, TraversableExpressionStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_expression_statement( + &mut self, + node: SharedBox<'a, TraversableExpressionStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_if_statement( + &mut self, + node: SharedBox<'a, TraversableIfStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_if_statement( + &mut self, + node: SharedBox<'a, TraversableIfStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_do_while_statement( + &mut self, + node: SharedBox<'a, TraversableDoWhileStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_do_while_statement( + &mut self, + node: SharedBox<'a, TraversableDoWhileStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_while_statement( + &mut self, + node: SharedBox<'a, TraversableWhileStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_while_statement( + &mut self, + node: SharedBox<'a, TraversableWhileStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_for_statement( + &mut self, + node: SharedBox<'a, TraversableForStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_for_statement( + &mut self, + node: SharedBox<'a, TraversableForStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_for_statement_init( + &mut self, + node: TraversableForStatementInit<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_for_statement_init( + &mut self, + node: TraversableForStatementInit<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_for_in_statement( + &mut self, + node: SharedBox<'a, TraversableForInStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_for_in_statement( + &mut self, + node: SharedBox<'a, TraversableForInStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_for_of_statement( + &mut self, + node: SharedBox<'a, TraversableForOfStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_for_of_statement( + &mut self, + node: SharedBox<'a, TraversableForOfStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_for_statement_left( + &mut self, + node: TraversableForStatementLeft<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_for_statement_left( + &mut self, + node: TraversableForStatementLeft<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_continue_statement( + &mut self, + node: SharedBox<'a, TraversableContinueStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_continue_statement( + &mut self, + node: SharedBox<'a, TraversableContinueStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_break_statement( + &mut self, + node: SharedBox<'a, TraversableBreakStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_break_statement( + &mut self, + node: SharedBox<'a, TraversableBreakStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_return_statement( + &mut self, + node: SharedBox<'a, TraversableReturnStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_return_statement( + &mut self, + node: SharedBox<'a, TraversableReturnStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_with_statement( + &mut self, + node: SharedBox<'a, TraversableWithStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_with_statement( + &mut self, + node: SharedBox<'a, TraversableWithStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_switch_statement( + &mut self, + node: SharedBox<'a, TraversableSwitchStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_switch_statement( + &mut self, + node: SharedBox<'a, TraversableSwitchStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_switch_case( + &mut self, + node: SharedBox<'a, TraversableSwitchCase<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_switch_case( + &mut self, + node: SharedBox<'a, TraversableSwitchCase<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_labeled_statement( + &mut self, + node: SharedBox<'a, TraversableLabeledStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_labeled_statement( + &mut self, + node: SharedBox<'a, TraversableLabeledStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_throw_statement( + &mut self, + node: SharedBox<'a, TraversableThrowStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_throw_statement( + &mut self, + node: SharedBox<'a, TraversableThrowStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_try_statement( + &mut self, + node: SharedBox<'a, TraversableTryStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_try_statement( + &mut self, + node: SharedBox<'a, TraversableTryStatement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_catch_clause( + &mut self, + node: SharedBox<'a, TraversableCatchClause<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_catch_clause( + &mut self, + node: SharedBox<'a, TraversableCatchClause<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_catch_parameter( + &mut self, + node: SharedBox<'a, TraversableCatchParameter<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_catch_parameter( + &mut self, + node: SharedBox<'a, TraversableCatchParameter<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_debugger_statement( + &mut self, + node: SharedBox<'a, TraversableDebuggerStatement>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_binding_pattern( + &mut self, + node: SharedBox<'a, TraversableBindingPattern<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_binding_pattern( + &mut self, + node: SharedBox<'a, TraversableBindingPattern<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_binding_pattern_kind( + &mut self, + node: TraversableBindingPatternKind<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_binding_pattern_kind( + &mut self, + node: TraversableBindingPatternKind<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_assignment_pattern( + &mut self, + node: SharedBox<'a, TraversableAssignmentPattern<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_assignment_pattern( + &mut self, + node: SharedBox<'a, TraversableAssignmentPattern<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_object_pattern( + &mut self, + node: SharedBox<'a, TraversableObjectPattern<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_object_pattern( + &mut self, + node: SharedBox<'a, TraversableObjectPattern<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_binding_property( + &mut self, + node: SharedBox<'a, TraversableBindingProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_binding_property( + &mut self, + node: SharedBox<'a, TraversableBindingProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_array_pattern( + &mut self, + node: SharedBox<'a, TraversableArrayPattern<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_array_pattern( + &mut self, + node: SharedBox<'a, TraversableArrayPattern<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_binding_rest_element( + &mut self, + node: SharedBox<'a, TraversableBindingRestElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_binding_rest_element( + &mut self, + node: SharedBox<'a, TraversableBindingRestElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_function( + &mut self, + node: SharedBox<'a, TraversableFunction<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_function( + &mut self, + node: SharedBox<'a, TraversableFunction<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_formal_parameters( + &mut self, + node: SharedBox<'a, TraversableFormalParameters<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_formal_parameters( + &mut self, + node: SharedBox<'a, TraversableFormalParameters<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_formal_parameter( + &mut self, + node: SharedBox<'a, TraversableFormalParameter<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_formal_parameter( + &mut self, + node: SharedBox<'a, TraversableFormalParameter<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_function_body( + &mut self, + node: SharedBox<'a, TraversableFunctionBody<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_function_body( + &mut self, + node: SharedBox<'a, TraversableFunctionBody<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_arrow_function_expression( + &mut self, + node: SharedBox<'a, TraversableArrowFunctionExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_arrow_function_expression( + &mut self, + node: SharedBox<'a, TraversableArrowFunctionExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_yield_expression( + &mut self, + node: SharedBox<'a, TraversableYieldExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_yield_expression( + &mut self, + node: SharedBox<'a, TraversableYieldExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_class( + &mut self, + node: SharedBox<'a, TraversableClass<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_class( + &mut self, + node: SharedBox<'a, TraversableClass<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_class_body( + &mut self, + node: SharedBox<'a, TraversableClassBody<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_class_body( + &mut self, + node: SharedBox<'a, TraversableClassBody<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_class_element( + &mut self, + node: TraversableClassElement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_class_element( + &mut self, + node: TraversableClassElement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_method_definition( + &mut self, + node: SharedBox<'a, TraversableMethodDefinition<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_method_definition( + &mut self, + node: SharedBox<'a, TraversableMethodDefinition<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_property_definition( + &mut self, + node: SharedBox<'a, TraversablePropertyDefinition<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_property_definition( + &mut self, + node: SharedBox<'a, TraversablePropertyDefinition<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_private_identifier( + &mut self, + node: SharedBox<'a, TraversablePrivateIdentifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_static_block( + &mut self, + node: SharedBox<'a, TraversableStaticBlock<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_static_block( + &mut self, + node: SharedBox<'a, TraversableStaticBlock<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_module_declaration( + &mut self, + node: TraversableModuleDeclaration<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_module_declaration( + &mut self, + node: TraversableModuleDeclaration<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_accessor_property( + &mut self, + node: SharedBox<'a, TraversableAccessorProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_accessor_property( + &mut self, + node: SharedBox<'a, TraversableAccessorProperty<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_import_expression( + &mut self, + node: SharedBox<'a, TraversableImportExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_import_expression( + &mut self, + node: SharedBox<'a, TraversableImportExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_import_declaration( + &mut self, + node: SharedBox<'a, TraversableImportDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_import_declaration( + &mut self, + node: SharedBox<'a, TraversableImportDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_import_declaration_specifier( + &mut self, + node: TraversableImportDeclarationSpecifier<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_import_declaration_specifier( + &mut self, + node: TraversableImportDeclarationSpecifier<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_import_specifier( + &mut self, + node: SharedBox<'a, TraversableImportSpecifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_import_specifier( + &mut self, + node: SharedBox<'a, TraversableImportSpecifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_import_default_specifier( + &mut self, + node: SharedBox<'a, TraversableImportDefaultSpecifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_import_default_specifier( + &mut self, + node: SharedBox<'a, TraversableImportDefaultSpecifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_import_namespace_specifier( + &mut self, + node: SharedBox<'a, TraversableImportNamespaceSpecifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_import_namespace_specifier( + &mut self, + node: SharedBox<'a, TraversableImportNamespaceSpecifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_with_clause( + &mut self, + node: SharedBox<'a, TraversableWithClause<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_with_clause( + &mut self, + node: SharedBox<'a, TraversableWithClause<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_import_attribute( + &mut self, + node: SharedBox<'a, TraversableImportAttribute<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_import_attribute( + &mut self, + node: SharedBox<'a, TraversableImportAttribute<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_import_attribute_key( + &mut self, + node: TraversableImportAttributeKey<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_import_attribute_key( + &mut self, + node: TraversableImportAttributeKey<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_export_named_declaration( + &mut self, + node: SharedBox<'a, TraversableExportNamedDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_export_named_declaration( + &mut self, + node: SharedBox<'a, TraversableExportNamedDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_export_default_declaration( + &mut self, + node: SharedBox<'a, TraversableExportDefaultDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_export_default_declaration( + &mut self, + node: SharedBox<'a, TraversableExportDefaultDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_export_all_declaration( + &mut self, + node: SharedBox<'a, TraversableExportAllDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_export_all_declaration( + &mut self, + node: SharedBox<'a, TraversableExportAllDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_export_specifier( + &mut self, + node: SharedBox<'a, TraversableExportSpecifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_export_specifier( + &mut self, + node: SharedBox<'a, TraversableExportSpecifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_export_default_declaration_kind( + &mut self, + node: TraversableExportDefaultDeclarationKind<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_export_default_declaration_kind( + &mut self, + node: TraversableExportDefaultDeclarationKind<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_module_export_name( + &mut self, + node: TraversableModuleExportName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_module_export_name( + &mut self, + node: TraversableModuleExportName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_element( + &mut self, + node: SharedBox<'a, TraversableJSXElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_element( + &mut self, + node: SharedBox<'a, TraversableJSXElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_opening_element( + &mut self, + node: SharedBox<'a, TraversableJSXOpeningElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_opening_element( + &mut self, + node: SharedBox<'a, TraversableJSXOpeningElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_closing_element( + &mut self, + node: SharedBox<'a, TraversableJSXClosingElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_closing_element( + &mut self, + node: SharedBox<'a, TraversableJSXClosingElement<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_fragment( + &mut self, + node: SharedBox<'a, TraversableJSXFragment<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_fragment( + &mut self, + node: SharedBox<'a, TraversableJSXFragment<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_element_name( + &mut self, + node: TraversableJSXElementName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_element_name( + &mut self, + node: TraversableJSXElementName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_namespaced_name( + &mut self, + node: SharedBox<'a, TraversableJSXNamespacedName<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_namespaced_name( + &mut self, + node: SharedBox<'a, TraversableJSXNamespacedName<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_member_expression( + &mut self, + node: SharedBox<'a, TraversableJSXMemberExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_member_expression( + &mut self, + node: SharedBox<'a, TraversableJSXMemberExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_member_expression_object( + &mut self, + node: TraversableJSXMemberExpressionObject<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_member_expression_object( + &mut self, + node: TraversableJSXMemberExpressionObject<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_expression_container( + &mut self, + node: SharedBox<'a, TraversableJSXExpressionContainer<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_expression_container( + &mut self, + node: SharedBox<'a, TraversableJSXExpressionContainer<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_expression( + &mut self, + node: TraversableJSXExpression<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_expression( + &mut self, + node: TraversableJSXExpression<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_jsx_empty_expression( + &mut self, + node: SharedBox<'a, TraversableJSXEmptyExpression>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_attribute_item( + &mut self, + node: TraversableJSXAttributeItem<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_attribute_item( + &mut self, + node: TraversableJSXAttributeItem<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_attribute( + &mut self, + node: SharedBox<'a, TraversableJSXAttribute<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_attribute( + &mut self, + node: SharedBox<'a, TraversableJSXAttribute<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_spread_attribute( + &mut self, + node: SharedBox<'a, TraversableJSXSpreadAttribute<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_spread_attribute( + &mut self, + node: SharedBox<'a, TraversableJSXSpreadAttribute<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_attribute_name( + &mut self, + node: TraversableJSXAttributeName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_attribute_name( + &mut self, + node: TraversableJSXAttributeName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_attribute_value( + &mut self, + node: TraversableJSXAttributeValue<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_attribute_value( + &mut self, + node: TraversableJSXAttributeValue<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_jsx_identifier( + &mut self, + node: SharedBox<'a, TraversableJSXIdentifier<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_child( + &mut self, + node: TraversableJSXChild<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_child( + &mut self, + node: TraversableJSXChild<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_jsx_spread_child( + &mut self, + node: SharedBox<'a, TraversableJSXSpreadChild<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_jsx_spread_child( + &mut self, + node: SharedBox<'a, TraversableJSXSpreadChild<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_jsx_text( + &mut self, + node: SharedBox<'a, TraversableJSXText<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_boolean_literal( + &mut self, + node: SharedBox<'a, TraversableBooleanLiteral>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_null_literal( + &mut self, + node: SharedBox<'a, TraversableNullLiteral>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_numeric_literal( + &mut self, + node: SharedBox<'a, TraversableNumericLiteral<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_big_int_literal( + &mut self, + node: SharedBox<'a, TraversableBigIntLiteral<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_reg_exp_literal( + &mut self, + node: SharedBox<'a, TraversableRegExpLiteral<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_string_literal( + &mut self, + node: SharedBox<'a, TraversableStringLiteral<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_this_parameter( + &mut self, + node: SharedBox<'a, TraversableTSThisParameter<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_this_parameter( + &mut self, + node: SharedBox<'a, TraversableTSThisParameter<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_enum_declaration( + &mut self, + node: SharedBox<'a, TraversableTSEnumDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_enum_declaration( + &mut self, + node: SharedBox<'a, TraversableTSEnumDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_enum_member( + &mut self, + node: SharedBox<'a, TraversableTSEnumMember<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_enum_member( + &mut self, + node: SharedBox<'a, TraversableTSEnumMember<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_enum_member_name( + &mut self, + node: TraversableTSEnumMemberName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_enum_member_name( + &mut self, + node: TraversableTSEnumMemberName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_annotation( + &mut self, + node: SharedBox<'a, TraversableTSTypeAnnotation<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_annotation( + &mut self, + node: SharedBox<'a, TraversableTSTypeAnnotation<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_literal_type( + &mut self, + node: SharedBox<'a, TraversableTSLiteralType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_literal_type( + &mut self, + node: SharedBox<'a, TraversableTSLiteralType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_literal( + &mut self, + node: TraversableTSLiteral<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_literal( + &mut self, + node: TraversableTSLiteral<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type( + &mut self, + node: TraversableTSType<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type(&mut self, node: TraversableTSType<'a>, ctx: &TraverseCtx<'a>, tk: &mut Token) { + } + + fn enter_ts_conditional_type( + &mut self, + node: SharedBox<'a, TraversableTSConditionalType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_conditional_type( + &mut self, + node: SharedBox<'a, TraversableTSConditionalType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_union_type( + &mut self, + node: SharedBox<'a, TraversableTSUnionType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_union_type( + &mut self, + node: SharedBox<'a, TraversableTSUnionType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_intersection_type( + &mut self, + node: SharedBox<'a, TraversableTSIntersectionType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_intersection_type( + &mut self, + node: SharedBox<'a, TraversableTSIntersectionType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_operator( + &mut self, + node: SharedBox<'a, TraversableTSTypeOperator<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_operator( + &mut self, + node: SharedBox<'a, TraversableTSTypeOperator<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_array_type( + &mut self, + node: SharedBox<'a, TraversableTSArrayType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_array_type( + &mut self, + node: SharedBox<'a, TraversableTSArrayType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_indexed_access_type( + &mut self, + node: SharedBox<'a, TraversableTSIndexedAccessType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_indexed_access_type( + &mut self, + node: SharedBox<'a, TraversableTSIndexedAccessType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_tuple_type( + &mut self, + node: SharedBox<'a, TraversableTSTupleType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_tuple_type( + &mut self, + node: SharedBox<'a, TraversableTSTupleType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_named_tuple_member( + &mut self, + node: SharedBox<'a, TraversableTSNamedTupleMember<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_named_tuple_member( + &mut self, + node: SharedBox<'a, TraversableTSNamedTupleMember<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_optional_type( + &mut self, + node: SharedBox<'a, TraversableTSOptionalType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_optional_type( + &mut self, + node: SharedBox<'a, TraversableTSOptionalType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_rest_type( + &mut self, + node: SharedBox<'a, TraversableTSRestType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_rest_type( + &mut self, + node: SharedBox<'a, TraversableTSRestType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_tuple_element( + &mut self, + node: TraversableTSTupleElement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_tuple_element( + &mut self, + node: TraversableTSTupleElement<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_any_keyword( + &mut self, + node: SharedBox<'a, TraversableTSAnyKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_string_keyword( + &mut self, + node: SharedBox<'a, TraversableTSStringKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_boolean_keyword( + &mut self, + node: SharedBox<'a, TraversableTSBooleanKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_number_keyword( + &mut self, + node: SharedBox<'a, TraversableTSNumberKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_never_keyword( + &mut self, + node: SharedBox<'a, TraversableTSNeverKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_unknown_keyword( + &mut self, + node: SharedBox<'a, TraversableTSUnknownKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_null_keyword( + &mut self, + node: SharedBox<'a, TraversableTSNullKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_undefined_keyword( + &mut self, + node: SharedBox<'a, TraversableTSUndefinedKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_void_keyword( + &mut self, + node: SharedBox<'a, TraversableTSVoidKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_symbol_keyword( + &mut self, + node: SharedBox<'a, TraversableTSSymbolKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_this_type( + &mut self, + node: SharedBox<'a, TraversableTSThisType>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_object_keyword( + &mut self, + node: SharedBox<'a, TraversableTSObjectKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_big_int_keyword( + &mut self, + node: SharedBox<'a, TraversableTSBigIntKeyword>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_reference( + &mut self, + node: SharedBox<'a, TraversableTSTypeReference<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_reference( + &mut self, + node: SharedBox<'a, TraversableTSTypeReference<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_name( + &mut self, + node: TraversableTSTypeName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_name( + &mut self, + node: TraversableTSTypeName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_qualified_name( + &mut self, + node: SharedBox<'a, TraversableTSQualifiedName<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_qualified_name( + &mut self, + node: SharedBox<'a, TraversableTSQualifiedName<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_parameter_instantiation( + &mut self, + node: SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_parameter_instantiation( + &mut self, + node: SharedBox<'a, TraversableTSTypeParameterInstantiation<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_parameter( + &mut self, + node: SharedBox<'a, TraversableTSTypeParameter<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_parameter( + &mut self, + node: SharedBox<'a, TraversableTSTypeParameter<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_parameter_declaration( + &mut self, + node: SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_parameter_declaration( + &mut self, + node: SharedBox<'a, TraversableTSTypeParameterDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_alias_declaration( + &mut self, + node: SharedBox<'a, TraversableTSTypeAliasDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_alias_declaration( + &mut self, + node: SharedBox<'a, TraversableTSTypeAliasDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_class_implements( + &mut self, + node: SharedBox<'a, TraversableTSClassImplements<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_class_implements( + &mut self, + node: SharedBox<'a, TraversableTSClassImplements<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_interface_declaration( + &mut self, + node: SharedBox<'a, TraversableTSInterfaceDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_interface_declaration( + &mut self, + node: SharedBox<'a, TraversableTSInterfaceDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_interface_body( + &mut self, + node: SharedBox<'a, TraversableTSInterfaceBody<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_interface_body( + &mut self, + node: SharedBox<'a, TraversableTSInterfaceBody<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_property_signature( + &mut self, + node: SharedBox<'a, TraversableTSPropertySignature<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_property_signature( + &mut self, + node: SharedBox<'a, TraversableTSPropertySignature<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_signature( + &mut self, + node: TraversableTSSignature<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_signature( + &mut self, + node: TraversableTSSignature<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_index_signature( + &mut self, + node: SharedBox<'a, TraversableTSIndexSignature<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_index_signature( + &mut self, + node: SharedBox<'a, TraversableTSIndexSignature<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_call_signature_declaration( + &mut self, + node: SharedBox<'a, TraversableTSCallSignatureDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_call_signature_declaration( + &mut self, + node: SharedBox<'a, TraversableTSCallSignatureDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_method_signature( + &mut self, + node: SharedBox<'a, TraversableTSMethodSignature<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_method_signature( + &mut self, + node: SharedBox<'a, TraversableTSMethodSignature<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_construct_signature_declaration( + &mut self, + node: SharedBox<'a, TraversableTSConstructSignatureDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_construct_signature_declaration( + &mut self, + node: SharedBox<'a, TraversableTSConstructSignatureDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_index_signature_name( + &mut self, + node: SharedBox<'a, TraversableTSIndexSignatureName<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_index_signature_name( + &mut self, + node: SharedBox<'a, TraversableTSIndexSignatureName<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_interface_heritage( + &mut self, + node: SharedBox<'a, TraversableTSInterfaceHeritage<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_interface_heritage( + &mut self, + node: SharedBox<'a, TraversableTSInterfaceHeritage<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_predicate( + &mut self, + node: SharedBox<'a, TraversableTSTypePredicate<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_predicate( + &mut self, + node: SharedBox<'a, TraversableTSTypePredicate<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_predicate_name( + &mut self, + node: TraversableTSTypePredicateName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_predicate_name( + &mut self, + node: TraversableTSTypePredicateName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_module_declaration( + &mut self, + node: SharedBox<'a, TraversableTSModuleDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_module_declaration( + &mut self, + node: SharedBox<'a, TraversableTSModuleDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_module_declaration_name( + &mut self, + node: TraversableTSModuleDeclarationName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_module_declaration_name( + &mut self, + node: TraversableTSModuleDeclarationName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_module_declaration_body( + &mut self, + node: TraversableTSModuleDeclarationBody<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_module_declaration_body( + &mut self, + node: TraversableTSModuleDeclarationBody<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_module_block( + &mut self, + node: SharedBox<'a, TraversableTSModuleBlock<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_module_block( + &mut self, + node: SharedBox<'a, TraversableTSModuleBlock<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_literal( + &mut self, + node: SharedBox<'a, TraversableTSTypeLiteral<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_literal( + &mut self, + node: SharedBox<'a, TraversableTSTypeLiteral<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_infer_type( + &mut self, + node: SharedBox<'a, TraversableTSInferType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_infer_type( + &mut self, + node: SharedBox<'a, TraversableTSInferType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_query( + &mut self, + node: SharedBox<'a, TraversableTSTypeQuery<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_query( + &mut self, + node: SharedBox<'a, TraversableTSTypeQuery<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_query_expr_name( + &mut self, + node: TraversableTSTypeQueryExprName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_query_expr_name( + &mut self, + node: TraversableTSTypeQueryExprName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_import_type( + &mut self, + node: SharedBox<'a, TraversableTSImportType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_import_type( + &mut self, + node: SharedBox<'a, TraversableTSImportType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_import_attributes( + &mut self, + node: SharedBox<'a, TraversableTSImportAttributes<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_import_attributes( + &mut self, + node: SharedBox<'a, TraversableTSImportAttributes<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_import_attribute( + &mut self, + node: SharedBox<'a, TraversableTSImportAttribute<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_import_attribute( + &mut self, + node: SharedBox<'a, TraversableTSImportAttribute<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_import_attribute_name( + &mut self, + node: TraversableTSImportAttributeName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_import_attribute_name( + &mut self, + node: TraversableTSImportAttributeName<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_function_type( + &mut self, + node: SharedBox<'a, TraversableTSFunctionType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_function_type( + &mut self, + node: SharedBox<'a, TraversableTSFunctionType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_constructor_type( + &mut self, + node: SharedBox<'a, TraversableTSConstructorType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_constructor_type( + &mut self, + node: SharedBox<'a, TraversableTSConstructorType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_mapped_type( + &mut self, + node: SharedBox<'a, TraversableTSMappedType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_mapped_type( + &mut self, + node: SharedBox<'a, TraversableTSMappedType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_template_literal_type( + &mut self, + node: SharedBox<'a, TraversableTSTemplateLiteralType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_template_literal_type( + &mut self, + node: SharedBox<'a, TraversableTSTemplateLiteralType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_as_expression( + &mut self, + node: SharedBox<'a, TraversableTSAsExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_as_expression( + &mut self, + node: SharedBox<'a, TraversableTSAsExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_satisfies_expression( + &mut self, + node: SharedBox<'a, TraversableTSSatisfiesExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_satisfies_expression( + &mut self, + node: SharedBox<'a, TraversableTSSatisfiesExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_type_assertion( + &mut self, + node: SharedBox<'a, TraversableTSTypeAssertion<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_type_assertion( + &mut self, + node: SharedBox<'a, TraversableTSTypeAssertion<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_import_equals_declaration( + &mut self, + node: SharedBox<'a, TraversableTSImportEqualsDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_import_equals_declaration( + &mut self, + node: SharedBox<'a, TraversableTSImportEqualsDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_module_reference( + &mut self, + node: TraversableTSModuleReference<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_module_reference( + &mut self, + node: TraversableTSModuleReference<'a>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_external_module_reference( + &mut self, + node: SharedBox<'a, TraversableTSExternalModuleReference<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_external_module_reference( + &mut self, + node: SharedBox<'a, TraversableTSExternalModuleReference<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_non_null_expression( + &mut self, + node: SharedBox<'a, TraversableTSNonNullExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_non_null_expression( + &mut self, + node: SharedBox<'a, TraversableTSNonNullExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_decorator( + &mut self, + node: SharedBox<'a, TraversableDecorator<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_decorator( + &mut self, + node: SharedBox<'a, TraversableDecorator<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_export_assignment( + &mut self, + node: SharedBox<'a, TraversableTSExportAssignment<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_export_assignment( + &mut self, + node: SharedBox<'a, TraversableTSExportAssignment<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_ts_namespace_export_declaration( + &mut self, + node: SharedBox<'a, TraversableTSNamespaceExportDeclaration<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_ts_instantiation_expression( + &mut self, + node: SharedBox<'a, TraversableTSInstantiationExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_ts_instantiation_expression( + &mut self, + node: SharedBox<'a, TraversableTSInstantiationExpression<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn enter_js_doc_nullable_type( + &mut self, + node: SharedBox<'a, TraversableJSDocNullableType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + fn exit_js_doc_nullable_type( + &mut self, + node: SharedBox<'a, TraversableJSDocNullableType<'a>>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } + + fn visit_js_doc_unknown_type( + &mut self, + node: SharedBox<'a, TraversableJSDocUnknownType>, + ctx: &TraverseCtx<'a>, + tk: &mut Token, + ) { + } +} diff --git a/crates/oxc_ast/src/visit/visit.rs b/crates/oxc_ast/src/visit/visit.rs index f8b7b1eee07c6..cc3c4ed9c7859 100644 --- a/crates/oxc_ast/src/visit/visit.rs +++ b/crates/oxc_ast/src/visit/visit.rs @@ -876,6 +876,8 @@ pub trait Visit<'a>: Sized { } pub mod walk { + use crate::dummy; + use super::*; pub fn walk_program<'a, V: Visit<'a>>(visitor: &mut V, program: &Program<'a>) { @@ -929,6 +931,7 @@ pub mod walk { visitor.visit_module_declaration(stmt.to_module_declaration()); } match_declaration!(Statement) => visitor.visit_declaration(stmt.to_declaration()), + Statement::Dummy => dummy!(), } } @@ -1027,6 +1030,7 @@ pub mod walk { visitor.visit_variable_declaration(decl); } match_expression!(ForStatementInit) => visitor.visit_expression(init.to_expression()), + ForStatementInit::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1074,6 +1078,7 @@ pub mod walk { ForStatementLeft::UsingDeclaration(decl) => { visitor.visit_using_declaration(decl); } + ForStatementLeft::Dummy => dummy!(), } } @@ -1364,6 +1369,7 @@ pub mod walk { ClassElement::PropertyDefinition(def) => visitor.visit_property_definition(def), ClassElement::AccessorProperty(_def) => { /* TODO */ } ClassElement::TSIndexSignature(sig) => visitor.visit_ts_index_signature(sig), + ClassElement::Dummy => dummy!(), } } @@ -1478,6 +1484,7 @@ pub mod walk { Expression::TSInstantiationExpression(expr) => { visitor.visit_ts_instantiation_expression(expr); } + Expression::Dummy => dummy!(), } } @@ -1508,6 +1515,7 @@ pub mod walk { visitor.visit_expression_array_element(arg.to_expression()); } ArrayExpressionElement::Elision(elision) => visitor.visit_elision(elision), + ArrayExpressionElement::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1518,6 +1526,7 @@ pub mod walk { match arg { Argument::SpreadElement(spread) => visitor.visit_spread_element(spread), match_expression!(Argument) => visitor.visit_expression(arg.to_expression()), + Argument::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1610,6 +1619,7 @@ pub mod walk { match_member_expression!(ChainElement) => { visitor.visit_member_expression(elem.to_member_expression()); } + ChainElement::Dummy => dummy!(), } } @@ -1659,6 +1669,7 @@ pub mod walk { MemberExpression::PrivateFieldExpression(expr) => { visitor.visit_private_field_expression(expr); } + MemberExpression::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1716,6 +1727,7 @@ pub mod walk { match prop { ObjectPropertyKind::ObjectProperty(prop) => visitor.visit_object_property(prop), ObjectPropertyKind::SpreadProperty(elem) => visitor.visit_spread_element(elem), + ObjectPropertyKind::Dummy => dummy!(), } } @@ -1736,6 +1748,7 @@ pub mod walk { match_expression!(PropertyKey) => { visitor.visit_expression(key.to_expression()); } + PropertyKey::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1832,6 +1845,7 @@ pub mod walk { match_assignment_target_pattern!(AssignmentTarget) => { visitor.visit_assignment_target_pattern(target.to_assignment_target_pattern()); } + AssignmentTarget::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1861,6 +1875,7 @@ pub mod walk { SimpleAssignmentTarget::TSTypeAssertion(expr) => { visitor.visit_expression(&expr.expression); } + SimpleAssignmentTarget::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1876,6 +1891,7 @@ pub mod walk { AssignmentTargetPattern::ObjectAssignmentTarget(target) => { visitor.visit_object_assignment_target(target); } + AssignmentTargetPattern::Dummy => dummy!(), } } @@ -1902,6 +1918,7 @@ pub mod walk { AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(target) => { visitor.visit_assignment_target_with_default(target); } + AssignmentTargetMaybeDefault::Dummy => dummy!(), } } @@ -1939,6 +1956,7 @@ pub mod walk { AssignmentTargetProperty::AssignmentTargetPropertyProperty(prop) => { visitor.visit_assignment_target_property_property(prop); } + AssignmentTargetProperty::Dummy => dummy!(), } } @@ -2012,6 +2030,7 @@ pub mod walk { JSXElementName::Identifier(ident) => visitor.visit_jsx_identifier(ident), JSXElementName::NamespacedName(expr) => visitor.visit_jsx_namespaced_name(expr), JSXElementName::MemberExpression(expr) => visitor.visit_jsx_member_expression(expr), + JSXElementName::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2044,6 +2063,7 @@ pub mod walk { JSXMemberExpressionObject::MemberExpression(expr) => { visitor.visit_jsx_member_expression(expr); } + JSXMemberExpressionObject::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2067,6 +2087,7 @@ pub mod walk { JSXAttributeItem::SpreadAttribute(attribute) => { visitor.visit_jsx_spread_attribute(attribute); } + JSXAttributeItem::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2095,6 +2116,7 @@ pub mod walk { JSXAttributeValue::Element(elem) => visitor.visit_jsx_element(elem), JSXAttributeValue::Fragment(elem) => visitor.visit_jsx_fragment(elem), JSXAttributeValue::StringLiteral(lit) => visitor.visit_string_literal(lit), + JSXAttributeValue::Dummy => dummy!(), } } @@ -2112,6 +2134,7 @@ pub mod walk { match expr { match_expression!(JSXExpression) => visitor.visit_expression(expr.to_expression()), JSXExpression::EmptyExpression(_) => {} + JSXExpression::Dummy => dummy!(), } } @@ -2131,6 +2154,7 @@ pub mod walk { JSXChild::ExpressionContainer(expr) => visitor.visit_jsx_expression_container(expr), JSXChild::Spread(expr) => visitor.visit_jsx_spread_child(expr), JSXChild::Text(expr) => visitor.visit_jsx_text(expr), + JSXChild::Dummy => dummy!(), } } @@ -2154,6 +2178,7 @@ pub mod walk { BindingPatternKind::ObjectPattern(pat) => visitor.visit_object_pattern(pat), BindingPatternKind::ArrayPattern(pat) => visitor.visit_array_pattern(pat), BindingPatternKind::AssignmentPattern(pat) => visitor.visit_assignment_pattern(pat), + BindingPatternKind::Dummy => dummy!(), } if let Some(type_annotation) = &pat.type_annotation { visitor.visit_ts_type_annotation(type_annotation); @@ -2322,6 +2347,7 @@ pub mod walk { visitor.visit_expression(&decl.expression); } ModuleDeclaration::TSNamespaceExportDeclaration(_) => {} + ModuleDeclaration::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2365,6 +2391,7 @@ pub mod walk { match key { ImportAttributeKey::Identifier(ident) => visitor.visit_identifier_name(ident), ImportAttributeKey::StringLiteral(ident) => visitor.visit_string_literal(ident), + ImportAttributeKey::Dummy => dummy!(), } } @@ -2382,6 +2409,7 @@ pub mod walk { ImportDeclarationSpecifier::ImportNamespaceSpecifier(specifier) => { visitor.visit_import_name_specifier(specifier); } + ImportDeclarationSpecifier::Dummy => dummy!(), } } @@ -2505,6 +2533,7 @@ pub mod walk { Declaration::TSInterfaceDeclaration(decl) => { visitor.visit_ts_interface_declaration(decl); } + Declaration::Dummy => dummy!(), } } @@ -2532,6 +2561,7 @@ pub mod walk { TSModuleReference::ExternalModuleReference(reference) => { visitor.visit_ts_external_module_reference(reference); } + TSModuleReference::Dummy => dummy!(), } } @@ -2541,6 +2571,7 @@ pub mod walk { match &name { TSTypeName::IdentifierReference(ident) => visitor.visit_identifier_reference(ident), TSTypeName::QualifiedName(name) => visitor.visit_ts_qualified_name(name), + TSTypeName::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2572,6 +2603,7 @@ pub mod walk { match &decl.id { TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident), TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit), + TSModuleDeclarationName::Dummy => dummy!(), } match &decl.body { Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => { @@ -2580,6 +2612,7 @@ pub mod walk { Some(TSModuleDeclarationBody::TSModuleBlock(block)) => { visitor.visit_ts_module_block(block); } + Some(TSModuleDeclarationBody::Dummy) => dummy!(), None => {} } visitor.leave_node(kind); @@ -2718,6 +2751,7 @@ pub mod walk { TSType::TSUnionType(ty) => visitor.visit_ts_union_type(ty), // JSDoc TSType::JSDocNullableType(_) | TSType::JSDocUnknownType(_) => { /* TODO */ } + TSType::Dummy => dummy!(), } } @@ -2762,6 +2796,7 @@ pub mod walk { match_ts_type!(TSTupleElement) => visitor.visit_ts_type(ty.to_ts_type()), TSTupleElement::TSOptionalType(ty) => visitor.visit_ts_type(&ty.type_annotation), TSTupleElement::TSRestType(ty) => visitor.visit_ts_type(&ty.type_annotation), + TSTupleElement::Dummy => dummy!(), }; } @@ -2902,6 +2937,7 @@ pub mod walk { TSLiteral::StringLiteral(lit) => visitor.visit_string_literal(lit), TSLiteral::TemplateLiteral(lit) => visitor.visit_template_literal(lit), TSLiteral::UnaryExpression(expr) => visitor.visit_unary_expression(expr), + TSLiteral::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2917,6 +2953,7 @@ pub mod walk { TSSignature::TSConstructSignatureDeclaration(sig) => { visitor.visit_ts_construct_signature_declaration(sig); } + TSSignature::Dummy => dummy!(), } } @@ -3002,6 +3039,7 @@ pub mod walk { visitor.visit_ts_type_name(name.to_ts_type_name()); } TSTypeQueryExprName::TSImportType(import) => visitor.visit_ts_import_type(import), + TSTypeQueryExprName::Dummy => dummy!(), } if let Some(type_parameters) = &ty.type_parameters { visitor.visit_ts_type_parameter_instantiation(type_parameters); @@ -3049,6 +3087,7 @@ pub mod walk { match name { TSImportAttributeName::Identifier(ident) => visitor.visit_identifier_name(ident), TSImportAttributeName::StringLiteral(ident) => visitor.visit_string_literal(ident), + TSImportAttributeName::Dummy => dummy!(), } } diff --git a/crates/oxc_ast/src/visit/visit_mut.rs b/crates/oxc_ast/src/visit/visit_mut.rs index 52b03ac0f5e1d..08d9ce0612b34 100644 --- a/crates/oxc_ast/src/visit/visit_mut.rs +++ b/crates/oxc_ast/src/visit/visit_mut.rs @@ -826,6 +826,8 @@ pub trait VisitMut<'a>: Sized { } pub mod walk_mut { + use crate::dummy; + use super::*; pub fn walk_program_mut<'a, V: VisitMut<'a>>(visitor: &mut V, program: &mut Program<'a>) { @@ -883,6 +885,7 @@ pub mod walk_mut { visitor.visit_module_declaration(stmt.to_module_declaration_mut()); } match_declaration!(Statement) => visitor.visit_declaration(stmt.to_declaration_mut()), + Statement::Dummy => dummy!(), } } @@ -1004,6 +1007,7 @@ pub mod walk_mut { ForStatementInit::UsingDeclaration(decl) => { visitor.visit_using_declaration(decl); } + ForStatementInit::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1060,6 +1064,7 @@ pub mod walk_mut { ForStatementLeft::UsingDeclaration(decl) => { visitor.visit_using_declaration(decl); } + ForStatementLeft::Dummy => dummy!(), } } @@ -1398,6 +1403,7 @@ pub mod walk_mut { ClassElement::PropertyDefinition(def) => visitor.visit_property_definition(def), ClassElement::AccessorProperty(_def) => { /* TODO */ } ClassElement::TSIndexSignature(sig) => visitor.visit_ts_index_signature(sig), + ClassElement::Dummy => dummy!(), } } @@ -1508,6 +1514,7 @@ pub mod walk_mut { Expression::TSInstantiationExpression(expr) => { visitor.visit_ts_instantiation_expression(expr); } + Expression::Dummy => dummy!(), } } @@ -1544,6 +1551,7 @@ pub mod walk_mut { visitor.visit_expression_array_element(arg.to_expression_mut()); } ArrayExpressionElement::Elision(elision) => visitor.visit_elision(elision), + ArrayExpressionElement::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1554,6 +1562,7 @@ pub mod walk_mut { match arg { Argument::SpreadElement(spread) => visitor.visit_spread_element(spread), match_expression!(Argument) => visitor.visit_expression(arg.to_expression_mut()), + Argument::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1667,6 +1676,7 @@ pub mod walk_mut { match_member_expression!(ChainElement) => { visitor.visit_member_expression(elem.to_member_expression_mut()); } + ChainElement::Dummy => dummy!(), } } @@ -1719,6 +1729,7 @@ pub mod walk_mut { MemberExpression::PrivateFieldExpression(expr) => { visitor.visit_private_field_expression(expr); } + MemberExpression::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1782,6 +1793,7 @@ pub mod walk_mut { match prop { ObjectPropertyKind::ObjectProperty(prop) => visitor.visit_object_property(prop), ObjectPropertyKind::SpreadProperty(elem) => visitor.visit_spread_element(elem), + ObjectPropertyKind::Dummy => dummy!(), } } @@ -1806,6 +1818,7 @@ pub mod walk_mut { PropertyKey::StaticIdentifier(ident) => visitor.visit_identifier_name(ident), PropertyKey::PrivateIdentifier(ident) => visitor.visit_private_identifier(ident), match_expression!(PropertyKey) => visitor.visit_expression(key.to_expression_mut()), + PropertyKey::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1911,6 +1924,7 @@ pub mod walk_mut { match_assignment_target_pattern!(AssignmentTarget) => { visitor.visit_assignment_target_pattern(target.to_assignment_target_pattern_mut()); } + AssignmentTarget::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1940,6 +1954,7 @@ pub mod walk_mut { SimpleAssignmentTarget::TSTypeAssertion(expr) => { visitor.visit_expression(&mut expr.expression); } + SimpleAssignmentTarget::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -1955,6 +1970,7 @@ pub mod walk_mut { AssignmentTargetPattern::ObjectAssignmentTarget(target) => { visitor.visit_object_assignment_target(target); } + AssignmentTargetPattern::Dummy => dummy!(), } } @@ -1981,6 +1997,7 @@ pub mod walk_mut { AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(target) => { visitor.visit_assignment_target_with_default(target); } + AssignmentTargetMaybeDefault::Dummy => dummy!(), } } @@ -2018,6 +2035,7 @@ pub mod walk_mut { AssignmentTargetProperty::AssignmentTargetPropertyProperty(prop) => { visitor.visit_assignment_target_property_property(prop); } + AssignmentTargetProperty::Dummy => dummy!(), } } @@ -2095,6 +2113,7 @@ pub mod walk_mut { JSXElementName::Identifier(ident) => visitor.visit_jsx_identifier(ident), JSXElementName::MemberExpression(expr) => visitor.visit_jsx_member_expression(expr), JSXElementName::NamespacedName(name) => visitor.visit_jsx_namespaced_name(name), + JSXElementName::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2130,6 +2149,7 @@ pub mod walk_mut { JSXMemberExpressionObject::MemberExpression(expr) => { visitor.visit_jsx_member_expression(expr); } + JSXMemberExpressionObject::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2156,6 +2176,7 @@ pub mod walk_mut { JSXAttributeItem::SpreadAttribute(attribute) => { visitor.visit_jsx_spread_attribute(attribute); } + JSXAttributeItem::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2187,6 +2208,7 @@ pub mod walk_mut { JSXAttributeValue::Element(elem) => visitor.visit_jsx_element(elem), JSXAttributeValue::Fragment(elem) => visitor.visit_jsx_fragment(elem), JSXAttributeValue::StringLiteral(_) => {} + JSXAttributeValue::Dummy => dummy!(), } } @@ -2207,6 +2229,7 @@ pub mod walk_mut { match expr { match_expression!(JSXExpression) => visitor.visit_expression(expr.to_expression_mut()), JSXExpression::EmptyExpression(_) => {} + JSXExpression::Dummy => dummy!(), } } @@ -2226,6 +2249,7 @@ pub mod walk_mut { JSXChild::ExpressionContainer(expr) => visitor.visit_jsx_expression_container(expr), JSXChild::Spread(expr) => visitor.visit_jsx_spread_child(expr), JSXChild::Text(expr) => visitor.visit_jsx_text(expr), + JSXChild::Dummy => dummy!(), } } @@ -2255,6 +2279,7 @@ pub mod walk_mut { BindingPatternKind::ObjectPattern(pat) => visitor.visit_object_pattern(pat), BindingPatternKind::ArrayPattern(pat) => visitor.visit_array_pattern(pat), BindingPatternKind::AssignmentPattern(pat) => visitor.visit_assignment_pattern(pat), + BindingPatternKind::Dummy => dummy!(), } if let Some(type_annotation) = &mut pat.type_annotation { visitor.visit_ts_type_annotation(type_annotation); @@ -2467,6 +2492,7 @@ pub mod walk_mut { visitor.visit_expression(&mut decl.expression); } ModuleDeclaration::TSNamespaceExportDeclaration(_) => {} + ModuleDeclaration::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2513,6 +2539,7 @@ pub mod walk_mut { match key { ImportAttributeKey::Identifier(ident) => visitor.visit_identifier_name(ident), ImportAttributeKey::StringLiteral(ident) => visitor.visit_string_literal(ident), + ImportAttributeKey::Dummy => dummy!(), } } @@ -2530,6 +2557,7 @@ pub mod walk_mut { ImportDeclarationSpecifier::ImportNamespaceSpecifier(specifier) => { visitor.visit_import_name_specifier(specifier); } + ImportDeclarationSpecifier::Dummy => dummy!(), } } @@ -2651,6 +2679,7 @@ pub mod walk_mut { Declaration::TSInterfaceDeclaration(decl) => { visitor.visit_ts_interface_declaration(decl); } + Declaration::Dummy => dummy!(), } } @@ -2678,6 +2707,7 @@ pub mod walk_mut { TSModuleReference::ExternalModuleReference(reference) => { visitor.visit_ts_external_module_reference(reference); } + TSModuleReference::Dummy => dummy!(), } } @@ -2687,6 +2717,7 @@ pub mod walk_mut { match name { TSTypeName::IdentifierReference(ident) => visitor.visit_identifier_reference(ident), TSTypeName::QualifiedName(name) => visitor.visit_ts_qualified_name(name), + TSTypeName::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -2721,6 +2752,7 @@ pub mod walk_mut { match &mut decl.id { TSModuleDeclarationName::Identifier(ident) => visitor.visit_identifier_name(ident), TSModuleDeclarationName::StringLiteral(lit) => visitor.visit_string_literal(lit), + TSModuleDeclarationName::Dummy => dummy!(), } match &mut decl.body { Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) => { @@ -2729,6 +2761,7 @@ pub mod walk_mut { Some(TSModuleDeclarationBody::TSModuleBlock(block)) => { visitor.visit_ts_module_block(block); } + Some(TSModuleDeclarationBody::Dummy) => dummy!(), None => {} } visitor.leave_node(kind); @@ -2914,6 +2947,7 @@ pub mod walk_mut { match_ts_type!(TSTupleElement) => visitor.visit_ts_type(ty.to_ts_type_mut()), TSTupleElement::TSOptionalType(ty) => visitor.visit_ts_type(&mut ty.type_annotation), TSTupleElement::TSRestType(ty) => visitor.visit_ts_type(&mut ty.type_annotation), + TSTupleElement::Dummy => dummy!(), }; } @@ -3075,6 +3109,7 @@ pub mod walk_mut { TSLiteral::StringLiteral(lit) => visitor.visit_string_literal(lit), TSLiteral::TemplateLiteral(lit) => visitor.visit_template_literal(lit), TSLiteral::UnaryExpression(expr) => visitor.visit_unary_expression(expr), + TSLiteral::Dummy => dummy!(), } visitor.leave_node(kind); } @@ -3093,6 +3128,7 @@ pub mod walk_mut { TSSignature::TSConstructSignatureDeclaration(sig) => { visitor.visit_ts_construct_signature_declaration(sig); } + TSSignature::Dummy => dummy!(), } } @@ -3178,6 +3214,7 @@ pub mod walk_mut { visitor.visit_ts_type_name(name.to_ts_type_name_mut()); } TSTypeQueryExprName::TSImportType(import) => visitor.visit_ts_import_type(import), + TSTypeQueryExprName::Dummy => dummy!(), } if let Some(type_parameters) = &mut ty.type_parameters { visitor.visit_ts_type_parameter_instantiation(type_parameters); @@ -3228,6 +3265,7 @@ pub mod walk_mut { match name { TSImportAttributeName::Identifier(ident) => visitor.visit_identifier_name(ident), TSImportAttributeName::StringLiteral(ident) => visitor.visit_string_literal(ident), + TSImportAttributeName::Dummy => dummy!(), } } } diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index e91ae1af14a6e..0d85c12c1b562 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -1,6 +1,7 @@ use oxc_allocator::{Box, Vec}; #[allow(clippy::wildcard_imports)] use oxc_ast::ast::*; +use oxc_ast::dummy; use oxc_span::GetSpan; use oxc_syntax::{ identifier::{LS, PS}, @@ -104,6 +105,7 @@ impl<'a, const MINIFY: bool> Gen for Statement<'a> { Self::WithStatement(stmt) => stmt.gen(p, ctx), match_module_declaration!(Self) => self.to_module_declaration().gen(p, ctx), match_declaration!(Self) => self.to_declaration().gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -230,6 +232,7 @@ impl<'a, const MINIFY: bool> Gen for ForStatement<'a> { init.to_expression().gen_expr(p, Precedence::lowest(), ctx); } ForStatementInit::VariableDeclaration(var) => var.gen(p, ctx), + ForStatementInit::Dummy => dummy!(), } } @@ -305,6 +308,7 @@ impl<'a, const MINIFY: bool> Gen for ForStatementLeft<'a> { match_assignment_target!(ForStatementLeft) => { p.wrap(false, |p| self.to_assignment_target().gen(p, ctx)); } + ForStatementLeft::Dummy => dummy!(), } } } @@ -517,6 +521,7 @@ impl<'a, const MINIFY: bool> Gen for ModuleDeclaration<'a> { p.print_semicolon_after_statement(); } } + Self::Dummy => dummy!(), } } } @@ -587,6 +592,7 @@ impl<'a, const MINIFY: bool> Gen for Declaration<'a> { decl.gen(p, ctx); } } + Self::Dummy => dummy!(), } } } @@ -784,6 +790,7 @@ impl<'a, const MINIFY: bool> Gen for ImportDeclaration<'a> { literal.gen(p, ctx); literal.value.as_bytes() } + ModuleExportName::Dummy => "Dummy ModuleExportName".as_bytes(), }; let local_name = spec.local.name.as_bytes(); @@ -793,6 +800,7 @@ impl<'a, const MINIFY: bool> Gen for ImportDeclaration<'a> { spec.local.gen(p, ctx); } } + ImportDeclarationSpecifier::Dummy => dummy!(), } } if in_block { @@ -810,7 +818,7 @@ impl<'a, const MINIFY: bool> Gen for ImportDeclaration<'a> { } } -impl<'a, const MINIFY: bool> Gen for Option> { +impl<'a, const MINIFY: bool> Gen for Option>> { fn gen(&self, p: &mut Codegen<{ MINIFY }>, ctx: Context) { if let Some(with_clause) = self { with_clause.gen(p, ctx); @@ -834,6 +842,7 @@ impl<'a, const MINIFY: bool> Gen for ImportAttribute<'a> { p.print_str(identifier.name.as_bytes()); } ImportAttributeKey::StringLiteral(literal) => literal.gen(p, ctx), + ImportAttributeKey::Dummy => dummy!(), }; p.print_colon(); self.value.gen(p, ctx); @@ -878,7 +887,7 @@ impl<'a, const MINIFY: bool> Gen for ExportSpecifier<'a> { p.print_str(b"type "); } self.local.gen(p, ctx); - if self.local.name() != self.exported.name() { + if self.local.as_atom() != self.exported.as_atom() { p.print_str(b" as "); self.exported.gen(p, ctx); } @@ -892,6 +901,7 @@ impl<'a, const MINIFY: bool> Gen for ModuleExportName<'a> { p.print_str(identifier.name.as_bytes()); } Self::StringLiteral(literal) => literal.gen(p, ctx), + Self::Dummy => dummy!(), }; } } @@ -949,6 +959,7 @@ impl<'a, const MINIFY: bool> Gen for ExportDefaultDeclarationKind<'a> { } Self::TSInterfaceDeclaration(interface) => interface.gen(p, ctx), Self::TSEnumDeclaration(enum_decl) => enum_decl.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -1004,6 +1015,7 @@ impl<'a, const MINIFY: bool> GenExpr for Expression<'a> { Self::TSTypeAssertion(e) => e.gen_expr(p, precedence, ctx), Self::TSNonNullExpression(e) => e.expression.gen_expr(p, precedence, ctx), Self::TSInstantiationExpression(e) => e.expression.gen_expr(p, precedence, ctx), + Self::Dummy => dummy!(), } } } @@ -1315,6 +1327,7 @@ impl<'a, const MINIFY: bool> GenExpr for MemberExpression<'a> { } Self::StaticMemberExpression(expr) => expr.gen_expr(p, self.precedence(), ctx), Self::PrivateFieldExpression(expr) => expr.gen_expr(p, self.precedence(), ctx), + Self::Dummy => dummy!(), }); } } @@ -1386,6 +1399,7 @@ impl<'a, const MINIFY: bool> Gen for Argument<'a> { match_expression!(Self) => { self.to_expression().gen_expr(p, Precedence::Assign, Context::default()); } + Self::Dummy => dummy!(), } } } @@ -1398,6 +1412,7 @@ impl<'a, const MINIFY: bool> Gen for ArrayExpressionElement<'a> { } Self::SpreadElement(elem) => elem.gen(p, ctx), Self::Elision(_span) => {} + Self::Dummy => dummy!(), } } } @@ -1457,6 +1472,7 @@ impl<'a, const MINIFY: bool> Gen for ObjectPropertyKind<'a> { match self { Self::ObjectProperty(prop) => prop.gen(p, ctx), Self::SpreadProperty(elem) => elem.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -1530,6 +1546,7 @@ impl<'a, const MINIFY: bool> Gen for PropertyKey<'a> { match_expression!(Self) => { self.to_expression().gen_expr(p, Precedence::Assign, Context::default()); } + Self::Dummy => dummy!(), } } } @@ -1775,6 +1792,7 @@ impl<'a, const MINIFY: bool> Gen for AssignmentTarget<'a> { match_assignment_target_pattern!(Self) => { self.to_assignment_target_pattern().gen(p, ctx); } + Self::Dummy => dummy!(), } } } @@ -1790,6 +1808,7 @@ impl<'a, const MINIFY: bool> GenExpr for SimpleAssignmentTarget<'a> { Self::TSSatisfiesExpression(e) => e.expression.gen_expr(p, precedence, ctx), Self::TSNonNullExpression(e) => e.expression.gen_expr(p, precedence, ctx), Self::TSTypeAssertion(e) => e.gen_expr(p, precedence, ctx), + Self::Dummy => dummy!(), } } } @@ -1799,6 +1818,7 @@ impl<'a, const MINIFY: bool> Gen for AssignmentTargetPattern<'a> { match self { Self::ArrayAssignmentTarget(target) => target.gen(p, ctx), Self::ObjectAssignmentTarget(target) => target.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -1853,6 +1873,7 @@ impl<'a, const MINIFY: bool> Gen for AssignmentTargetMaybeDefault<'a> { match self { match_assignment_target!(Self) => self.to_assignment_target().gen(p, ctx), Self::AssignmentTargetWithDefault(target) => target.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -1870,6 +1891,7 @@ impl<'a, const MINIFY: bool> Gen for AssignmentTargetProperty<'a> { match self { Self::AssignmentTargetPropertyIdentifier(ident) => ident.gen(p, ctx), Self::AssignmentTargetPropertyProperty(prop) => prop.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -1898,6 +1920,7 @@ impl<'a, const MINIFY: bool> Gen for AssignmentTargetPropertyProperty<'a key.to_expression().gen_expr(p, Precedence::Assign, Context::default()); p.print(b']'); } + PropertyKey::Dummy => dummy!(), } p.print_colon(); self.binding.gen(p, ctx); @@ -1988,6 +2011,7 @@ impl<'a, const MINIFY: bool> GenExpr for ChainExpression<'a> { match_member_expression!(ChainElement) => { self.expression.to_member_expression().gen_expr(p, precedence, ctx); } + ChainElement::Dummy => dummy!(), } } } @@ -2069,6 +2093,7 @@ impl<'a, const MINIFY: bool> Gen for ClassElement<'a> { Self::PropertyDefinition(elem) => elem.gen(p, ctx), Self::AccessorProperty(elem) => elem.gen(p, ctx), Self::TSIndexSignature(elem) => elem.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -2085,6 +2110,7 @@ impl<'a, const MINIFY: bool> Gen for JSXMemberExpressionObject<'a> { match self { Self::Identifier(ident) => ident.gen(p, ctx), Self::MemberExpression(member_expr) => member_expr.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -2103,6 +2129,7 @@ impl<'a, const MINIFY: bool> Gen for JSXElementName<'a> { Self::Identifier(identifier) => identifier.gen(p, ctx), Self::NamespacedName(namespaced_name) => namespaced_name.gen(p, ctx), Self::MemberExpression(member_expr) => member_expr.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -2120,6 +2147,7 @@ impl<'a, const MINIFY: bool> Gen for JSXAttributeName<'a> { match self { Self::Identifier(ident) => ident.gen(p, ctx), Self::NamespacedName(namespaced_name) => namespaced_name.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -2143,6 +2171,7 @@ impl<'a, const MINIFY: bool> Gen for JSXExpression<'a> { match self { match_expression!(Self) => p.print_expression(self.to_expression()), Self::EmptyExpression(expr) => expr.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -2162,6 +2191,7 @@ impl<'a, const MINIFY: bool> Gen for JSXAttributeValue<'a> { Self::Element(el) => el.gen(p, ctx), Self::StringLiteral(lit) => lit.gen(p, ctx), Self::ExpressionContainer(expr_container) => expr_container.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -2179,6 +2209,7 @@ impl<'a, const MINIFY: bool> Gen for JSXAttributeItem<'a> { match self { Self::Attribute(attr) => attr.gen(p, ctx), Self::SpreadAttribute(spread_attr) => spread_attr.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -2257,6 +2288,7 @@ impl<'a, const MINIFY: bool> Gen for JSXChild<'a> { Self::Spread(spread) => p.print_expression(&spread.expression), Self::ExpressionContainer(expr_container) => expr_container.gen(p, ctx), Self::Text(text) => text.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -2429,6 +2461,7 @@ impl<'a, const MINIFY: bool> Gen for BindingPattern<'a> { BindingPatternKind::ObjectPattern(pattern) => pattern.gen(p, ctx), BindingPatternKind::ArrayPattern(pattern) => pattern.gen(p, ctx), BindingPatternKind::AssignmentPattern(pattern) => pattern.gen(p, ctx), + BindingPatternKind::Dummy => dummy!(), } if p.options.enable_typescript { if self.optional { diff --git a/crates/oxc_codegen/src/gen_ts.rs b/crates/oxc_codegen/src/gen_ts.rs index 2ce94c0b329e4..58c9d8583caa0 100644 --- a/crates/oxc_codegen/src/gen_ts.rs +++ b/crates/oxc_codegen/src/gen_ts.rs @@ -2,6 +2,7 @@ use crate::context::Context; use crate::{Codegen, Gen, GenExpr}; #[allow(clippy::wildcard_imports)] use oxc_ast::ast::*; +use oxc_ast::dummy; use oxc_syntax::precedence::Precedence; impl<'a, const MINIFY: bool> Gen for TSTypeParameterDeclaration<'a> { @@ -227,6 +228,7 @@ impl<'a, const MINIFY: bool> Gen for TSType<'a> { TSTypePredicateName::This(_ident) => { p.print_str(b"this"); } + TSTypePredicateName::Dummy => dummy!(), } if let Some(type_annotation) = &decl.type_annotation { p.print_str(b" is "); @@ -250,6 +252,7 @@ impl<'a, const MINIFY: bool> Gen for TSType<'a> { } } Self::JSDocUnknownType(_decl) => p.print_str(b"unknown"), + Self::Dummy => dummy!(), } } } @@ -281,6 +284,7 @@ impl<'a, const MINIFY: bool> Gen for TSTypeName<'a> { p.print_str(b"."); decl.right.gen(p, ctx); } + Self::Dummy => dummy!(), } } } @@ -296,6 +300,7 @@ impl<'a, const MINIFY: bool> Gen for TSLiteral<'a> { Self::StringLiteral(decl) => decl.gen(p, ctx), Self::TemplateLiteral(decl) => decl.gen(p, ctx), Self::UnaryExpression(decl) => decl.gen_expr(p, Precedence::Assign, ctx), + Self::Dummy => dummy!(), } } } @@ -367,6 +372,7 @@ impl<'a, const MINIFY: bool> Gen for TSSignature<'a> { key @ match_expression!(PropertyKey) => { key.to_expression().gen_expr(p, Precedence::Assign, ctx); } + PropertyKey::Dummy => dummy!(), } } if signature.optional { @@ -420,6 +426,7 @@ impl<'a, const MINIFY: bool> Gen for TSSignature<'a> { key @ match_expression!(PropertyKey) => { key.to_expression().gen_expr(p, Precedence::Assign, ctx); } + PropertyKey::Dummy => dummy!(), } } if signature.optional { @@ -434,6 +441,7 @@ impl<'a, const MINIFY: bool> Gen for TSSignature<'a> { return_type.gen(p, ctx); } } + Self::Dummy => dummy!(), } } } @@ -453,6 +461,7 @@ impl<'a, const MINIFY: bool> Gen for TSTypeQueryExprName<'a> { match self { match_ts_type_name!(Self) => self.to_ts_type_name().gen(p, ctx), Self::TSImportType(decl) => decl.gen(p, ctx), + Self::Dummy => dummy!(), } } } @@ -507,6 +516,7 @@ impl<'a, const MINIFY: bool> Gen for TSTupleElement<'a> { p.print_str(b"..."); ts_type.type_annotation.gen(p, ctx); } + TSTupleElement::Dummy => dummy!(), } } } @@ -530,8 +540,8 @@ impl<'a, const MINIFY: bool> Gen for TSModuleDeclaration<'a> { } p.print_str(b"module"); p.print_space_before_identifier(); - let name = self.id.name(); - p.wrap_quote(name, |p, _| p.print_str(name.as_bytes())); + let name = self.id.as_atom(); + p.wrap_quote(name.as_str(), |p, _| p.print_str(name.as_bytes())); p.print_hard_space(); match &self.body { Some(TSModuleDeclarationBody::TSModuleDeclaration(body)) => { @@ -548,6 +558,7 @@ impl<'a, const MINIFY: bool> Gen for TSModuleDeclaration<'a> { p.print_semicolon_if_needed(); p.print_block_end(body.span.end); } + Some(TSModuleDeclarationBody::Dummy) => dummy!(), None => {} } if MINIFY { @@ -640,6 +651,7 @@ impl<'a, const MINIFY: bool> Gen for TSEnumMember<'a> { decl.to_expression().gen_expr(p, Precedence::lowest(), ctx); p.print_str(b"]"); } + TSEnumMemberName::Dummy => dummy!(), } } } @@ -684,6 +696,7 @@ impl<'a, const MINIFY: bool> Gen for TSModuleReference<'a> { p.print_str(b")"); } match_ts_type_name!(Self) => self.to_ts_type_name().gen(p, ctx), + Self::Dummy => dummy!(), } } } diff --git a/crates/oxc_linter/src/ast_util.rs b/crates/oxc_linter/src/ast_util.rs index 4c47ccc10f9c9..f6f42aa8ac281 100644 --- a/crates/oxc_linter/src/ast_util.rs +++ b/crates/oxc_linter/src/ast_util.rs @@ -1,6 +1,6 @@ use std::hash::{Hash, Hasher}; -use oxc_ast::AstKind; +use oxc_ast::{dummy, AstKind}; use oxc_semantic::{AstNode, SymbolId}; use oxc_span::{GetSpan, Span}; use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator}; @@ -166,6 +166,7 @@ impl<'a, 'b> IsConstant<'a, 'b> for Argument<'a> { match self { Self::SpreadElement(element) => element.is_constant(in_boolean_position, ctx), match_expression!(Self) => self.to_expression().is_constant(in_boolean_position, ctx), + Self::Dummy => dummy!(), } } } @@ -176,6 +177,7 @@ impl<'a, 'b> IsConstant<'a, 'b> for ArrayExpressionElement<'a> { Self::SpreadElement(element) => element.is_constant(in_boolean_position, ctx), match_expression!(Self) => self.to_expression().is_constant(in_boolean_position, ctx), Self::Elision(_) => true, + Self::Dummy => dummy!(), } } } diff --git a/crates/oxc_linter/src/rules/deepscan/bad_array_method_on_arguments.rs b/crates/oxc_linter/src/rules/deepscan/bad_array_method_on_arguments.rs index 65650f419dfee..db40a2ded6bf7 100644 --- a/crates/oxc_linter/src/rules/deepscan/bad_array_method_on_arguments.rs +++ b/crates/oxc_linter/src/rules/deepscan/bad_array_method_on_arguments.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{Expression, MemberExpression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -97,6 +97,7 @@ impl Rule for BadArrayMethodOnArguments { } } MemberExpression::PrivateFieldExpression(_) => {} + MemberExpression::Dummy => dummy!(unreachable), } } } diff --git a/crates/oxc_linter/src/rules/deepscan/uninvoked_array_callback.rs b/crates/oxc_linter/src/rules/deepscan/uninvoked_array_callback.rs index e70508d4799d0..1484330fc3b50 100644 --- a/crates/oxc_linter/src/rules/deepscan/uninvoked_array_callback.rs +++ b/crates/oxc_linter/src/rules/deepscan/uninvoked_array_callback.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{Argument, MemberExpression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -77,6 +77,7 @@ impl Rule for UninvokedArrayCallback { MemberExpression::ComputedMemberExpression(expr) => expr.expression.span(), MemberExpression::StaticMemberExpression(expr) => expr.property.span, MemberExpression::PrivateFieldExpression(expr) => expr.field.span, + MemberExpression::Dummy => dummy!(unreachable), }; ctx.diagnostic(UninvokedArrayCallbackDiagnostic(property_span, new_expr.span)); } diff --git a/crates/oxc_linter/src/rules/eslint/getter_return.rs b/crates/oxc_linter/src/rules/eslint/getter_return.rs index dd35cac022bbf..a2fc3c01cd0c1 100644 --- a/crates/oxc_linter/src/rules/eslint/getter_return.rs +++ b/crates/oxc_linter/src/rules/eslint/getter_return.rs @@ -3,7 +3,7 @@ use oxc_ast::{ match_member_expression, ChainElement, Expression, MemberExpression, MethodDefinitionKind, ObjectProperty, PropertyKind, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -100,6 +100,7 @@ impl GetterReturn { ChainElement::CallExpression(_) => { false // todo: make a test for this } + ChainElement::Dummy => dummy!(unreachable), }, _ => false, } diff --git a/crates/oxc_linter/src/rules/eslint/no_self_assign.rs b/crates/oxc_linter/src/rules/eslint/no_self_assign.rs index c75836516c727..2012d19c26149 100644 --- a/crates/oxc_linter/src/rules/eslint/no_self_assign.rs +++ b/crates/oxc_linter/src/rules/eslint/no_self_assign.rs @@ -4,7 +4,7 @@ use oxc_ast::{ AssignmentTarget, AssignmentTargetMaybeDefault, AssignmentTargetProperty, Expression, MemberExpression, ObjectProperty, ObjectPropertyKind, SimpleAssignmentTarget, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -162,6 +162,7 @@ impl NoSelfAssign { } } } + AssignmentTarget::Dummy => dummy!(unreachable), } } @@ -255,6 +256,7 @@ impl NoSelfAssign { AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(_) => { return; } + AssignmentTargetMaybeDefault::Dummy => dummy!(unreachable), }; if let ObjectPropertyKind::ObjectProperty(obj_prop) = right { if let ObjectProperty { method: false, value: expr, key, .. } = &**obj_prop { @@ -267,6 +269,7 @@ impl NoSelfAssign { } } AssignmentTargetProperty::AssignmentTargetPropertyIdentifier(_) => {} + AssignmentTargetProperty::Dummy => dummy!(unreachable), } } } diff --git a/crates/oxc_linter/src/rules/eslint/no_useless_rename.rs b/crates/oxc_linter/src/rules/eslint/no_useless_rename.rs index d8241bb31a6a1..91512563bc17b 100644 --- a/crates/oxc_linter/src/rules/eslint/no_useless_rename.rs +++ b/crates/oxc_linter/src/rules/eslint/no_useless_rename.rs @@ -138,7 +138,8 @@ impl Rule for NoUselessRename { AstKind::ImportSpecifier(import_specifier) => { if !self.ignore_import && import_specifier.imported.span() != import_specifier.local.span - && import_specifier.local.name == import_specifier.imported.name() + && import_specifier.local.name + == import_specifier.imported.name().map_or_else(|| "", |atom| atom.as_str()) { ctx.diagnostic(NoUselessRenameDiagnostic(import_specifier.local.span)); } diff --git a/crates/oxc_linter/src/rules/import/no_named_as_default_member.rs b/crates/oxc_linter/src/rules/import/no_named_as_default_member.rs index c971933660b61..07d19b82ce8f2 100644 --- a/crates/oxc_linter/src/rules/import/no_named_as_default_member.rs +++ b/crates/oxc_linter/src/rules/import/no_named_as_default_member.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use dashmap::mapref::one::Ref; use oxc_ast::{ ast::{BindingPatternKind, Expression, IdentifierReference, MemberExpression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -107,6 +107,7 @@ impl Rule for NoNamedAsDefaultMember { MemberExpression::ComputedMemberExpression(it) => it.span, MemberExpression::StaticMemberExpression(it) => it.span, MemberExpression::PrivateFieldExpression(it) => it.span, + MemberExpression::Dummy => dummy!(unreachable), }, ident.name.to_string(), prop_str.to_string(), diff --git a/crates/oxc_linter/src/rules/jest/prefer_spy_on.rs b/crates/oxc_linter/src/rules/jest/prefer_spy_on.rs index d5ca2709dbae3..35b286d723943 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_spy_on.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_spy_on.rs @@ -3,7 +3,7 @@ use oxc_ast::{ Argument, AssignmentExpression, CallExpression, Expression, MemberExpression, SimpleAssignmentTarget, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -158,6 +158,7 @@ impl PreferSpyOn { formatter.print_str(format!("\'{name}\'").as_bytes()); } MemberExpression::PrivateFieldExpression(_) => (), + MemberExpression::Dummy => dummy!(unreachable), } formatter.print(b')'); diff --git a/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs b/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs index e5b3c5cbfa889..abdabc776d65d 100644 --- a/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs +++ b/crates/oxc_linter/src/rules/jest/prefer_to_have_length.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{match_member_expression, CallExpression, Expression, MemberExpression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -104,6 +104,7 @@ impl PreferToHaveLength { ctx, ), MemberExpression::PrivateFieldExpression(_) => (), + MemberExpression::Dummy => dummy!(unreachable), }; } Expression::CallExpression(expr_call_expr) => { diff --git a/crates/oxc_linter/src/rules/jest/valid_describe_callback.rs b/crates/oxc_linter/src/rules/jest/valid_describe_callback.rs index b5a43e68cb273..59d05dfa9c83e 100644 --- a/crates/oxc_linter/src/rules/jest/valid_describe_callback.rs +++ b/crates/oxc_linter/src/rules/jest/valid_describe_callback.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{Argument, Expression, FunctionBody, Statement}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -135,6 +135,7 @@ fn run<'a>(possible_jest_node: &PossibleJestNode<'a, '_>, ctx: &LintContext<'a>) diagnostic(ctx, span, Message::UnexpectedReturnInDescribe); } } + Argument::Dummy => dummy!(unreachable), callback => diagnostic(ctx, callback.span(), Message::SecondArgumentMustBeFunction), } } diff --git a/crates/oxc_linter/src/rules/jsx_a11y/anchor_is_valid.rs b/crates/oxc_linter/src/rules/jsx_a11y/anchor_is_valid.rs index 9d41f2d80555b..66f3a9d3597be 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/anchor_is_valid.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/anchor_is_valid.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{JSXAttributeItem, JSXAttributeValue, JSXElementName, JSXExpression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -163,6 +163,7 @@ impl Rule for AnchorIsValid { // pass return; } + JSXAttributeItem::Dummy => dummy!(unreachable), } return; } @@ -171,6 +172,7 @@ impl Rule for AnchorIsValid { jsx_el.opening_element.attributes.iter().any(|attr| match attr { JSXAttributeItem::SpreadAttribute(_) => true, JSXAttributeItem::Attribute(_) => false, + JSXAttributeItem::Dummy => dummy!(unreachable), }); if has_spreed_attr { return; @@ -204,6 +206,7 @@ fn check_value_is_empty(value: &JSXAttributeValue, valid_hrefs: &[String]) -> bo _ => false, }, JSXAttributeValue::Fragment(_) => true, + JSXAttributeValue::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/jsx_a11y/aria_unsupported_elements.rs b/crates/oxc_linter/src/rules/jsx_a11y/aria_unsupported_elements.rs index 3d34b88306922..3ceb9e9caf5d1 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/aria_unsupported_elements.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/aria_unsupported_elements.rs @@ -1,4 +1,4 @@ -use oxc_ast::{ast::JSXAttributeItem, AstKind}; +use oxc_ast::{ast::JSXAttributeItem, dummy, AstKind}; use oxc_diagnostics::{ miette::{self, Diagnostic}, thiserror::Error, @@ -52,6 +52,7 @@ impl Rule for AriaUnsupportedElements { let attr = match attr { JSXAttributeItem::Attribute(attr) => attr, JSXAttributeItem::SpreadAttribute(_) => continue, + JSXAttributeItem::Dummy => dummy!(unreachable), }; let attr_name = get_jsx_attribute_name(&attr.name).to_lowercase(); if INVALID_ATTRIBUTES.contains(&attr_name) { diff --git a/crates/oxc_linter/src/rules/jsx_a11y/autocomplete_valid.rs b/crates/oxc_linter/src/rules/jsx_a11y/autocomplete_valid.rs index c2d39752d9cfc..436de71444bdf 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/autocomplete_valid.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/autocomplete_valid.rs @@ -6,7 +6,7 @@ use crate::{ }; use oxc_ast::{ ast::{JSXAttributeItem, JSXAttributeValue}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -193,6 +193,7 @@ impl Rule for AutocompleteValid { let attr = match autocomplete_prop { JSXAttributeItem::Attribute(attr) => attr, JSXAttributeItem::SpreadAttribute(_) => return, + JSXAttributeItem::Dummy => dummy!(unreachable), }; let Some(JSXAttributeValue::StringLiteral(autocomplete_values)) = &attr.value else { return; diff --git a/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs b/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs index 86ce0db6c9bd1..5205014f7abdf 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/img_redundant_alt.rs @@ -2,7 +2,7 @@ use regex::Regex; use oxc_ast::{ ast::{JSXAttributeItem, JSXAttributeName, JSXAttributeValue, JSXExpression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -131,11 +131,13 @@ impl Rule for ImgRedundantAlt { JSXAttributeItem::SpreadAttribute(_) => { return; } + JSXAttributeItem::Dummy => dummy!(unreachable), }; let alt_attribute_name_span = match alt_attribute_name { JSXAttributeName::Identifier(iden) => iden.span, JSXAttributeName::NamespacedName(namespaced_name) => namespaced_name.span, + JSXAttributeName::Dummy => dummy!(unreachable), }; match alt_attribute { diff --git a/crates/oxc_linter/src/rules/jsx_a11y/no_aria_hidden_on_focusable.rs b/crates/oxc_linter/src/rules/jsx_a11y/no_aria_hidden_on_focusable.rs index 6868664bdd227..66409e0978c73 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/no_aria_hidden_on_focusable.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/no_aria_hidden_on_focusable.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{JSXAttributeItem, JSXAttributeValue, JSXOpeningElement}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -64,6 +64,7 @@ fn is_aria_hidden_true(attr: &JSXAttributeItem) -> bool { _ => false, }, JSXAttributeItem::SpreadAttribute(_) => false, + JSXAttributeItem::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/jsx_a11y/scope.rs b/crates/oxc_linter/src/rules/jsx_a11y/scope.rs index 59f07a24f7d17..071a894407c1a 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/scope.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/scope.rs @@ -1,4 +1,4 @@ -use oxc_ast::{ast::JSXAttributeItem, AstKind}; +use oxc_ast::{ast::JSXAttributeItem, dummy, AstKind}; use oxc_diagnostics::{ miette::{self, Diagnostic}, thiserror::Error, @@ -57,6 +57,7 @@ impl Rule for Scope { JSXAttributeItem::SpreadAttribute(_) => { return; } + JSXAttributeItem::Dummy => dummy!(unreachable), }, None => { return; diff --git a/crates/oxc_linter/src/rules/jsx_a11y/tabindex_no_positive.rs b/crates/oxc_linter/src/rules/jsx_a11y/tabindex_no_positive.rs index ff6eca72f30d7..739da533bba41 100644 --- a/crates/oxc_linter/src/rules/jsx_a11y/tabindex_no_positive.rs +++ b/crates/oxc_linter/src/rules/jsx_a11y/tabindex_no_positive.rs @@ -1,4 +1,4 @@ -use oxc_ast::{ast::JSXAttributeItem, AstKind}; +use oxc_ast::{ast::JSXAttributeItem, dummy, AstKind}; use oxc_diagnostics::{ miette::{self, Diagnostic}, thiserror::Error, @@ -62,6 +62,7 @@ fn check_and_diagnose(attr: &JSXAttributeItem, ctx: &LintContext<'_>) { } }), JSXAttributeItem::SpreadAttribute(_) => {} + JSXAttributeItem::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/nextjs/inline_script_id.rs b/crates/oxc_linter/src/rules/nextjs/inline_script_id.rs index 267b958abcf3b..d470db3a61555 100644 --- a/crates/oxc_linter/src/rules/nextjs/inline_script_id.rs +++ b/crates/oxc_linter/src/rules/nextjs/inline_script_id.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{Expression, JSXAttributeItem, JSXAttributeName, ObjectPropertyKind, PropertyKey}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -88,6 +88,7 @@ impl Rule for InlineScriptId { continue 'references_loop; } } + JSXAttributeItem::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/oxc/misrefactored_assign_op.rs b/crates/oxc_linter/src/rules/oxc/misrefactored_assign_op.rs index 5c36f2a0a8bb0..9d0d1e4b6d212 100644 --- a/crates/oxc_linter/src/rules/oxc/misrefactored_assign_op.rs +++ b/crates/oxc_linter/src/rules/oxc/misrefactored_assign_op.rs @@ -1,7 +1,7 @@ // Based on https://github.com/rust-lang/rust-clippy//blob/c9a43b18f11219fa70fe632b29518581fcd589c8/clippy_lints/src/operators/misrefactored_assign_op.rs use oxc_ast::{ ast::{match_member_expression, AssignmentTarget, Expression, SimpleAssignmentTarget}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -127,6 +127,7 @@ fn assignment_target_eq_expr<'a>( SimpleAssignmentTarget::TSTypeAssertion(ts_expr) => { is_same_reference(&ts_expr.expression, right_expr, ctx) } + SimpleAssignmentTarget::Dummy => dummy!(unreachable), }; } diff --git a/crates/oxc_linter/src/rules/react/jsx_key.rs b/crates/oxc_linter/src/rules/react/jsx_key.rs index be93eae7b4a4a..d462374762e0f 100644 --- a/crates/oxc_linter/src/rules/react/jsx_key.rs +++ b/crates/oxc_linter/src/rules/react/jsx_key.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{JSXAttributeItem, JSXAttributeName, JSXElement, JSXFragment, Statement}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -178,6 +178,7 @@ fn check_jsx_element_is_key_before_spread<'a>(jsx_elem: &JSXElement<'a>, ctx: &L } } JSXAttributeItem::SpreadAttribute(_) => spread_idx = Some(i), + JSXAttributeItem::Dummy => dummy!(unreachable), } if key_idx_span.map(|x| x.0).is_some() && spread_idx.is_some() { break; diff --git a/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs b/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs index 9e8c6ea347db2..778deb9f697ce 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_target_blank.rs @@ -3,7 +3,7 @@ use oxc_ast::{ match_expression, Expression, JSXAttributeItem, JSXAttributeName, JSXAttributeValue, JSXElementName, JSXExpression, StringLiteral, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -179,6 +179,7 @@ impl Rule for JsxNoTargetBlank { has_href_value = true; }; } + JSXAttributeItem::Dummy => dummy!(unreachable), }); if is_warn_on_spread_attributes { @@ -351,10 +352,11 @@ fn check_rel<'a>( (check_rel_val(str, allow_referrer), "", false, false) } JSXAttributeValue::ExpressionContainer(expr) => match &expr.expression { - JSXExpression::EmptyExpression(_) => default, expr @ match_expression!(JSXExpression) => { match_rel_expression(expr.to_expression(), allow_referrer) } + JSXExpression::EmptyExpression(_) => default, + JSXExpression::Dummy => dummy!(unreachable), }, _ => default, } diff --git a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs index 2244dcc41fa9f..bef344dda6376 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_undef.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_undef.rs @@ -3,7 +3,7 @@ use oxc_ast::{ JSXElementName, JSXIdentifier, JSXMemberExpression, JSXMemberExpressionObject, JSXOpeningElement, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -42,6 +42,7 @@ fn get_member_ident<'a>(expr: &'a JSXMemberExpression<'a>) -> &'a JSXIdentifier match expr.object { JSXMemberExpressionObject::Identifier(ref ident) => ident, JSXMemberExpressionObject::MemberExpression(ref next_expr) => get_member_ident(next_expr), + JSXMemberExpressionObject::Dummy => dummy!(unreachable), } } fn get_resolvable_ident<'a>(node: &'a JSXElementName<'a>) -> Option<&'a JSXIdentifier> { @@ -53,6 +54,7 @@ fn get_resolvable_ident<'a>(node: &'a JSXElementName<'a>) -> Option<&'a JSXIdent } JSXElementName::Identifier(_) | JSXElementName::NamespacedName(_) => None, JSXElementName::MemberExpression(expr) => Some(get_member_ident(expr)), + JSXElementName::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs b/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs index d1ba17c51abe9..abb894fb808dd 100644 --- a/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs +++ b/crates/oxc_linter/src/rules/react/jsx_no_useless_fragment.rs @@ -3,7 +3,7 @@ use oxc_ast::{ JSXAttributeItem, JSXAttributeName, JSXChild, JSXElement, JSXElementName, JSXExpression, JSXFragment, JSXMemberExpressionObject, JSXOpeningElement, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -171,6 +171,7 @@ fn is_jsx_fragment(elem: &JSXOpeningElement) -> bool { return ident.name.as_str() == "React"; } JSXElementName::NamespacedName(_) => false, + JSXElementName::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs b/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs index d6182348ad6f9..29300e9e00ca5 100644 --- a/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs +++ b/crates/oxc_linter/src/rules/react/no_direct_mutation_state.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{Expression, MethodDefinitionKind, SimpleAssignmentTarget, StaticMemberExpression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -119,6 +119,7 @@ fn get_outer_member_expression<'a, 'b>( return Some(node); } } + SimpleAssignmentTarget::Dummy => dummy!(unreachable), _ => None, } } diff --git a/crates/oxc_linter/src/rules/react/no_unknown_property.rs b/crates/oxc_linter/src/rules/react/no_unknown_property.rs index 504b06b35367d..a1ea60e6db5a8 100644 --- a/crates/oxc_linter/src/rules/react/no_unknown_property.rs +++ b/crates/oxc_linter/src/rules/react/no_unknown_property.rs @@ -2,7 +2,7 @@ use itertools::Itertools; use once_cell::sync::Lazy; use oxc_ast::{ ast::{JSXAttributeItem, JSXAttributeName, JSXElementName}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -476,6 +476,7 @@ impl Rule for NoUnknownProperty { .filter_map(|attr| match &attr { JSXAttributeItem::Attribute(regular) => Some(&**regular), JSXAttributeItem::SpreadAttribute(_) => None, + JSXAttributeItem::Dummy => dummy!(unreachable), }) .for_each(|attr| { let span = attr.name.span(); diff --git a/crates/oxc_linter/src/rules/react/void_dom_elements_no_children.rs b/crates/oxc_linter/src/rules/react/void_dom_elements_no_children.rs index 931c476844107..03e04aa9b9f8e 100644 --- a/crates/oxc_linter/src/rules/react/void_dom_elements_no_children.rs +++ b/crates/oxc_linter/src/rules/react/void_dom_elements_no_children.rs @@ -3,7 +3,7 @@ use oxc_ast::{ Argument, JSXAttributeItem, JSXAttributeName, JSXElementName, ObjectPropertyKind, PropertyKey, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -81,6 +81,7 @@ impl Rule for VoidDomElementsNoChildren { iden.name == "children" || iden.name == "dangerouslySetInnerHTML" } JSXAttributeItem::SpreadAttribute(_) => false, + JSXAttributeItem::Dummy => dummy!(unreachable), }); if !jsx_el.children.is_empty() || has_children_attribute_or_danger { @@ -125,6 +126,7 @@ impl Rule for VoidDomElementsNoChildren { _ => false, }, ObjectPropertyKind::SpreadProperty(_) => false, + ObjectPropertyKind::Dummy => dummy!(unreachable), }); if call_expr.arguments.get(2).is_some() || has_children_prop_or_danger { diff --git a/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/listener_map.rs b/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/listener_map.rs index 4739173f6c797..439174a9c5b6c 100644 --- a/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/listener_map.rs +++ b/crates/oxc_linter/src/rules/tree_shaking/no_side_effects_in_initialization/listener_map.rs @@ -12,7 +12,7 @@ use oxc_ast::{ SimpleAssignmentTarget, Statement, StaticMemberExpression, ThisExpression, VariableDeclarator, }, - AstKind, + dummy, AstKind, }; use oxc_semantic::{AstNode, SymbolId}; use oxc_span::{GetSpan, Span}; @@ -189,6 +189,7 @@ impl<'a> ListenerMap for ForStatementInit<'a> { Self::VariableDeclaration(decl) => { decl.declarations.iter().for_each(|decl| decl.report_effects(options)); } + Self::Dummy => dummy!(unreachable), } } } @@ -409,6 +410,7 @@ impl<'a> ListenerMap for BindingPattern<'a> { assign_p.left.report_effects(options); assign_p.right.report_effects(options); } + BindingPatternKind::Dummy => dummy!(unreachable), } } fn report_effects_when_called(&self, options: &NodeListenerOptions) { @@ -709,6 +711,7 @@ impl<'a> ListenerMap for Argument<'a> { Self::SpreadElement(spread) => { spread.argument.report_effects(options); } + Self::Dummy => dummy!(unreachable), } } } @@ -720,6 +723,7 @@ impl<'a> ListenerMap for AssignmentTarget<'a> { self.to_simple_assignment_target().report_effects_when_assigned(options); } Self::ArrayAssignmentTarget(_) | Self::ObjectAssignmentTarget(_) => {} + Self::Dummy => dummy!(unreachable), } } } @@ -814,6 +818,7 @@ impl<'a> ListenerMap for MemberExpression<'a> { Self::PrivateFieldExpression(expr) => { expr.report_effects(options); } + Self::Dummy => dummy!(unreachable), } } fn report_effects_when_assigned(&self, options: &NodeListenerOptions) { @@ -830,6 +835,7 @@ impl<'a> ListenerMap for MemberExpression<'a> { expr.report_effects(options); expr.object.report_effects_when_mutated(options); } + Self::Dummy => dummy!(unreachable), } } } @@ -861,6 +867,7 @@ impl<'a> ListenerMap for ArrayExpressionElement<'a> { spreed.argument.report_effects(options); } Self::Elision(_) => {} + Self::Dummy => dummy!(unreachable), } } } diff --git a/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs b/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs index 09166515efb26..9f5f48cc10f60 100644 --- a/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs +++ b/crates/oxc_linter/src/rules/typescript/adjacent_overload_signatures.rs @@ -3,7 +3,7 @@ use oxc_ast::{ match_expression, ClassElement, Declaration, ExportDefaultDeclarationKind, FunctionType, ModuleDeclaration, PropertyKey, Statement, TSSignature, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -98,6 +98,7 @@ fn get_kind_from_key(key: &PropertyKey) -> MethodKind { | PropertyKey::RegExpLiteral(_) | PropertyKey::NullLiteral(_) => MethodKind::Quoted, match_expression!(PropertyKey) => MethodKind::Expression, + PropertyKey::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/typescript/ban_types.rs b/crates/oxc_linter/src/rules/typescript/ban_types.rs index 51951055e5d02..54fa93b564be7 100644 --- a/crates/oxc_linter/src/rules/typescript/ban_types.rs +++ b/crates/oxc_linter/src/rules/typescript/ban_types.rs @@ -1,4 +1,4 @@ -use oxc_ast::AstKind; +use oxc_ast::{dummy, AstKind}; use oxc_diagnostics::{ miette::{self, Diagnostic}, thiserror::{self, Error}, @@ -58,6 +58,7 @@ impl Rule for BanTypes { let name = match &typ.type_name { oxc_ast::ast::TSTypeName::IdentifierReference(v) => &v.name, oxc_ast::ast::TSTypeName::QualifiedName(_) => return, + oxc_ast::ast::TSTypeName::Dummy => dummy!(unreachable), }; match name.as_str() { diff --git a/crates/oxc_linter/src/rules/typescript/no_this_alias.rs b/crates/oxc_linter/src/rules/typescript/no_this_alias.rs index e3d62deb2500f..63028cfc88c8e 100644 --- a/crates/oxc_linter/src/rules/typescript/no_this_alias.rs +++ b/crates/oxc_linter/src/rules/typescript/no_this_alias.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{match_simple_assignment_target, AssignmentTarget, BindingPatternKind, Expression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -150,6 +150,7 @@ impl Rule for NoThisAlias { } } } + AssignmentTarget::Dummy => dummy!(unreachable), } } _ => {} diff --git a/crates/oxc_linter/src/rules/typescript/prefer_function_type.rs b/crates/oxc_linter/src/rules/typescript/prefer_function_type.rs index 1cc0115839247..20a81386a9b7d 100644 --- a/crates/oxc_linter/src/rules/typescript/prefer_function_type.rs +++ b/crates/oxc_linter/src/rules/typescript/prefer_function_type.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{ExportDefaultDeclarationKind, Expression, TSInterfaceDeclaration, TSSignature, TSType}, - AstKind, CommentKind, + dummy, AstKind, CommentKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -336,6 +336,7 @@ fn check_member(member: &TSSignature, node: &AstNode<'_>, ctx: &LintContext<'_>) | TSSignature::TSIndexSignature(_) | TSSignature::TSPropertySignature(_) | TSSignature::TSMethodSignature(_) => {} + TSSignature::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/typescript/triple_slash_reference.rs b/crates/oxc_linter/src/rules/typescript/triple_slash_reference.rs index c23e905f01a8f..284575eabf634 100644 --- a/crates/oxc_linter/src/rules/typescript/triple_slash_reference.rs +++ b/crates/oxc_linter/src/rules/typescript/triple_slash_reference.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use oxc_ast::{ ast::{Statement, TSModuleReference}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -145,6 +145,7 @@ impl Rule for TripleSlashReference { } TSModuleReference::IdentifierReference(_) | TSModuleReference::QualifiedName(_) => {} + TSModuleReference::Dummy => dummy!(unreachable), }, Statement::ImportDeclaration(decl) => { if let Some(v) = refs_for_import.get(decl.source.value.as_str()) { diff --git a/crates/oxc_linter/src/rules/unicorn/error_message.rs b/crates/oxc_linter/src/rules/unicorn/error_message.rs index 77216bc770c48..ecf6925b32893 100644 --- a/crates/oxc_linter/src/rules/unicorn/error_message.rs +++ b/crates/oxc_linter/src/rules/unicorn/error_message.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{Argument, CallExpression, Expression, NewExpression}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -72,11 +72,14 @@ impl Rule for ErrorMessage { let message_argument_idx = usize::from(constructor_name.as_str() == "AggregateError"); // If message is `SpreadElement` or there is `SpreadElement` before message - if args - .iter() - .enumerate() - .any(|(i, arg)| i <= message_argument_idx && matches!(arg, Argument::SpreadElement(_))) - { + if args.iter().enumerate().any(|(i, arg)| { + i <= message_argument_idx + && match arg { + Argument::SpreadElement(_) => true, + Argument::Dummy => dummy!(unreachable), + _ => false, + } + }) { return; } @@ -106,6 +109,7 @@ impl Rule for ErrorMessage { Argument::ArrayExpression(array_expr) => { ctx.diagnostic(ErrorMessageDiagnostic::NotString(array_expr.span)); } + Argument::Dummy => dummy!(unreachable), _ => {} } } diff --git a/crates/oxc_linter/src/rules/unicorn/no_static_only_class.rs b/crates/oxc_linter/src/rules/unicorn/no_static_only_class.rs index a54ef876834d0..ea92be3c0f1e1 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_static_only_class.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_static_only_class.rs @@ -1,4 +1,4 @@ -use oxc_ast::AstKind; +use oxc_ast::{dummy, AstKind}; use oxc_diagnostics::{ miette::{self, Diagnostic}, thiserror::Error, @@ -77,6 +77,7 @@ impl Rule for NoStaticOnlyClass { oxc_ast::ast::ClassElement::AccessorProperty(_) | oxc_ast::ast::ClassElement::StaticBlock(_) | oxc_ast::ast::ClassElement::TSIndexSignature(_) => {} + oxc_ast::ast::ClassElement::Dummy => dummy!(unreachable), } if node.r#static() { diff --git a/crates/oxc_linter/src/rules/unicorn/no_thenable.rs b/crates/oxc_linter/src/rules/unicorn/no_thenable.rs index 3811380b2b101..c6fe94260bdc0 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_thenable.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_thenable.rs @@ -4,7 +4,7 @@ use oxc_ast::{ BindingPatternKind, CallExpression, Declaration, Expression, ModuleDeclaration, ModuleExportName, ObjectPropertyKind, PropertyKey, VariableDeclarator, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -116,6 +116,7 @@ impl Rule for NoThenable { ctx.diagnostic(NoThenableDiagnostic::Export(lit.span)); } } + ModuleExportName::Dummy => dummy!(unreachable), } } } @@ -132,6 +133,7 @@ impl Rule for NoThenable { ctx.diagnostic(NoThenableDiagnostic::Class(expr.span)); } } + AssignmentTarget::Dummy => dummy!(unreachable), _ => {} }, _ => {} @@ -224,6 +226,7 @@ fn check_binding_pattern(pat: &BindingPatternKind, ctx: &LintContext) { BindingPatternKind::AssignmentPattern(assign) => { check_binding_pattern(&assign.left.kind, ctx); } + BindingPatternKind::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/unicorn/no_useless_spread.rs b/crates/oxc_linter/src/rules/unicorn/no_useless_spread.rs index 974b694ca0aa3..e5e581375165e 100644 --- a/crates/oxc_linter/src/rules/unicorn/no_useless_spread.rs +++ b/crates/oxc_linter/src/rules/unicorn/no_useless_spread.rs @@ -3,7 +3,7 @@ use oxc_ast::{ match_expression, Argument, ArrayExpression, ArrayExpressionElement, CallExpression, Expression, }, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -376,6 +376,7 @@ fn innermost_paren_arg_span(arg: &Argument) -> Span { match arg { match_expression!(Argument) => arg.to_expression().without_parenthesized().span(), Argument::SpreadElement(spread_elem) => spread_elem.argument.span(), + Argument::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/rules/unicorn/prefer_optional_catch_binding.rs b/crates/oxc_linter/src/rules/unicorn/prefer_optional_catch_binding.rs index dee733b77ff00..ec2d4baa27ed1 100644 --- a/crates/oxc_linter/src/rules/unicorn/prefer_optional_catch_binding.rs +++ b/crates/oxc_linter/src/rules/unicorn/prefer_optional_catch_binding.rs @@ -1,6 +1,6 @@ use oxc_ast::{ ast::{BindingPattern, BindingPatternKind}, - AstKind, + dummy, AstKind, }; use oxc_diagnostics::{ miette::{self, Diagnostic}, @@ -83,6 +83,7 @@ fn get_param_references_count(binding_pat: &BindingPattern, ctx: &LintContext) - count } + BindingPatternKind::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_linter/src/utils/jest.rs b/crates/oxc_linter/src/utils/jest.rs index 29f8f781b0121..e4eb153c4f8bf 100644 --- a/crates/oxc_linter/src/utils/jest.rs +++ b/crates/oxc_linter/src/utils/jest.rs @@ -232,7 +232,7 @@ fn find_original_name<'a>( import_decl.specifiers.iter().flatten().find_map(|specifier| match specifier { ImportDeclarationSpecifier::ImportSpecifier(import_specifier) => { if import_specifier.local.name.as_str() == name { - return Some(import_specifier.imported.name()); + return import_specifier.imported.name(); } None } diff --git a/crates/oxc_linter/src/utils/jest/parse_jest_fn.rs b/crates/oxc_linter/src/utils/jest/parse_jest_fn.rs index 1161224a6feff..cc3e130ab3a23 100644 --- a/crates/oxc_linter/src/utils/jest/parse_jest_fn.rs +++ b/crates/oxc_linter/src/utils/jest/parse_jest_fn.rs @@ -5,7 +5,7 @@ use oxc_ast::{ match_member_expression, Argument, CallExpression, Expression, IdentifierName, IdentifierReference, MemberExpression, }, - AstKind, + dummy, AstKind, }; use oxc_semantic::AstNode; use oxc_span::{Atom, Span}; @@ -423,6 +423,7 @@ impl<'a> MemberExpressionElement<'a> { } // Jest fn chains don't have private fields, just ignore it. MemberExpression::PrivateFieldExpression(_) => None, + MemberExpression::Dummy => dummy!(unreachable), } } pub fn is_string_literal(&self) -> bool { diff --git a/crates/oxc_linter/src/utils/react.rs b/crates/oxc_linter/src/utils/react.rs index a553bafbdb8fe..1fc06285ae02d 100644 --- a/crates/oxc_linter/src/utils/react.rs +++ b/crates/oxc_linter/src/utils/react.rs @@ -3,7 +3,7 @@ use oxc_ast::{ CallExpression, Expression, JSXAttributeItem, JSXAttributeName, JSXAttributeValue, JSXChild, JSXElement, JSXElementName, JSXExpression, JSXOpeningElement, }, - AstKind, + dummy, AstKind, }; use oxc_semantic::{AstNode, SymbolFlags}; @@ -32,6 +32,7 @@ pub fn has_jsx_prop<'a, 'b>( name.name.as_str() == target_prop } + JSXAttributeItem::Dummy => dummy!(unreachable), }) } @@ -46,6 +47,7 @@ pub fn has_jsx_prop_lowercase<'a, 'b>( name.name.as_str().to_lowercase() == target_prop.to_lowercase() } + JSXAttributeItem::Dummy => dummy!(unreachable), }) } @@ -63,6 +65,7 @@ pub fn get_jsx_attribute_name(attr: &JSXAttributeName) -> String { format!("{}:{}", name.namespace.name, name.property.name) } JSXAttributeName::Identifier(ident) => ident.name.to_string(), + JSXAttributeName::Dummy => "Dummy JSXAttributeName".to_string(), } } diff --git a/crates/oxc_macros/src/ast_node.rs b/crates/oxc_macros/src/ast_node.rs new file mode 100644 index 0000000000000..cec5327445a66 --- /dev/null +++ b/crates/oxc_macros/src/ast_node.rs @@ -0,0 +1,531 @@ +use proc_macro2::TokenStream as TokenStream2; + +use quote::{format_ident, quote}; +use syn::{ + parse_quote, punctuated::Punctuated, AngleBracketedGenericArguments, Attribute, Expr, + ExprGroup, ExprLit, Field, Fields, GenericArgument, Ident, ImplItemFn, Item, ItemEnum, + ItemStruct, Lit, Meta, Path, PathArguments, PathSegment, Token, Type, TypePath, TypeReference, + Variant, +}; + +const TRAVERSABLE: &str = "Traversable"; + +pub fn ast_node(mut item: Item) -> TokenStream2 { + let result = match &mut item { + Item::Struct(it) => modify_struct(it), + Item::Enum(it) => modify_enum(it), + _ => panic!("ast_node attribute can only be used on enums and structure types!"), + }; + + let ident = result.ident; + + let traversable_mod = format_ident!("traversable_{}", ident.to_string().to_lowercase()); + + let traversable = result.traversable; + + let output = quote! { + #[derive(layout_inspect::Inspect)] + #item + + pub mod #traversable_mod { + use super::*; + + #traversable + } + }; + + // dbg!(&output.to_string()); + output +} + +fn modify_struct(item: &mut ItemStruct) -> NodeData { + let mut has_repr_attr = false; + for attr in &item.attrs { + if attr.path().is_ident("repr") { + // TODO: Check is `#[repr(C)]` + has_repr_attr = true; + } + } + + item.fields.iter().for_each(validate_field); + // add the correct representation + if !has_repr_attr { + item.attrs.push(parse_quote!(#[repr(C)])); + } + NodeData { ident: &item.ident, traversable: generate_traversable_struct(item) } +} + +fn modify_enum(item: &mut ItemEnum) -> NodeData { + let mut has_repr_attr = false; + for attr in &item.attrs { + if attr.path().is_ident("repr") { + // TODO: Check is `#[repr(C, u8)]` + has_repr_attr = true; + } + } + + assert!( + item.variants.len() <= 128, + "`ast_node` enums are limited to a maximum of 128 variants." + ); + item.variants.iter().for_each(validate_variant); + // add the correct representation + if !has_repr_attr { + item.attrs.push(parse_quote!(#[repr(C, u8)])); + } + + // add explicit discriminants to all variants + let mut next_discriminant = 0u8; + item.variants.iter_mut().for_each(|var| { + if let Some((.., expr)) = &var.discriminant { + // Explicit discriminant + let discriminant = match expr { + Expr::Lit(ExprLit { lit: Lit::Int(lit), .. }) => { + Some(lit.base10_parse::().unwrap()) + } + Expr::Group(ExprGroup { expr, .. }) => { + if let Expr::Lit(ExprLit { lit: Lit::Int(lit), .. }) = &**expr { + Some(lit.base10_parse::().unwrap()) + } else { + None + } + } + _ => None, + }; + + if let Some(discriminant) = discriminant { + next_discriminant = discriminant + 1; + } else { + panic!("`ast_node` attribute only supports integers as explicit discriminators"); + } + } else { + // No explicit discriminant - create discriminant following last + var.discriminant = Some((parse_quote!(=), parse_quote!(#next_discriminant))); + next_discriminant += 1; + }; + }); + + assert!( + next_discriminant <= 128, + "Explicit discriminants must be less than 128 and must not cause later unspecified discriminants to reach 128" + ); + + // add the dummy variant. + // using 128 as discriminant so other discriminants can be compared with cheap AND operations. + item.variants.push(parse_quote!(Dummy = 128)); + + NodeData { ident: &item.ident, traversable: generate_traversable_enum(item) } +} + +// validators +// there are only here for early errors we still do some in-depth checks while generating the +// traversable modules. + +fn validate_field(field: &Field) { + assert!( + match &field.ty { + Type::Path(ty) if ty.path.segments.len() == 1 => true, + Type::Reference(_) => true, + _ => false, + }, + "Currently `ast_node` attribute only supports single segment type paths and references." + ); +} + +fn validate_variant(var: &Variant) { + assert_ne!( + var.ident, "Dummy", + r#"Found a variant called `Dummy`,\ + Please use another name,\ + This variant identifier is reserved by `ast_node` attribute."# + ); + + assert!( + matches!(var.fields, Fields::Unnamed(_) | Fields::Unit), + "Currently, `ast_node` attribute only supports unnamed and unit enum variants." + ); +} + +// generators + +fn generate_traversable_struct(item: &ItemStruct) -> TokenStream2 { + let ident = format_ident!("{TRAVERSABLE}{}", item.ident); + let generics = &item.generics; + + let fields = transform_fields(&item.fields); + let methods: Vec<_> = fields.iter().flat_map(generate_traversable_methods).collect(); + + // TODO: traits like serialization, Debug and Hash fail with `GCell`; + // But we may want to keep other attributes. + let output = quote! { + #[repr(C)] // TODO: we can derive attributes from `item` if we filter invalid attributes. + pub struct #ident #generics { + #fields + } + + impl #generics #ident #generics { + #(#methods)* + } + + impl #generics GCell<#ident #generics> { + + } + }; + + output +} + +fn generate_traversable_enum(item: &ItemEnum) -> TokenStream2 { + let ident = format_ident!("{TRAVERSABLE}{}", item.ident); + let generics = &item.generics; + + let variants = transform_variants(&item.variants); + + // TODO: traits like serialization, Debug and Hash fail with `GCell`; + // But we may want to keep other attributes. + let output = quote! { + #[repr(C, u8)] + // #(#attributes)* + pub enum #ident #generics { + #variants + } + }; + + output +} + +fn generate_traversable_methods(field: &Field) -> Vec { + let type_name = &type_name(&field.ty); + let mut methods = Vec::new(); + + // Early reaturn if we are visiting a non traversable/shared type. + if !is_traversable_type_name(type_name) && !is_shared_type_name(type_name) { + return methods; + } + + let v = &mut methods; + + if is_collection(type_name) { + generate_traversable_vec_methods(v, field); + } + + if is_ast_enum_type_name(type_name) { + generate_traversable_enum_method(v, field); + } else { + generate_traversable_struct_method(v, field); + } + + methods +} + +fn generate_traversable_vec_methods(v: &mut Vec, field: &Field) { + let ident = + field.ident.as_ref().expect("`ast_node` attribute only supports named struct fields."); + + debug_assert_eq!(ident, "SharedVec"); + + let ty = &field.ty; + let (_lifetime, ref generic_ty) = { + let generics = type_generics(ty).expect("We only accept generic collections."); + let mut iter = (&generics.args).into_iter(); + let GenericArgument::Lifetime(lifetime) = + iter.next().expect("`ast_node` only support's arena vectors") + else { + panic!("`ast_node` expected the first argument to the `Vec` to be a lifetime."); + }; + let GenericArgument::Type(generic_ty) = + iter.next().expect("`ast_node` only accepts arena vectors.") + else { + panic!("`ast_node` expected the second argument to the `Vec` to be a generic type argument."); + }; + + assert!(iter.next().is_none(), "`ast_node` only accepts arena vectors."); + + (lifetime, transform_type(generic_ty.clone())) + }; + + TraversableStructVecMethodsGenerator { ident, generic_ty }.generate(v); +} + +struct TraversableStructVecMethodsGenerator<'a> { + ident: &'a Ident, + generic_ty: &'a Type, +} + +impl<'a> TraversableStructVecMethodsGenerator<'a> { + fn generate_as_struct(self, _: &mut Vec) { + #![allow(clippy::unused_self)] + // TODO: implement me when we stabilized the struct version of these methods + } + + fn generate_as_enum(self, v: &mut Vec) { + macro_rules! vquote { + ($($tt:tt)*) => {{ + v.push(parse_quote!($($tt)*)) + }}; + } + let ident = self.ident; + let generic_ty = self.generic_ty; + + let ident_len = format_ident!("{ident}_len"); + let ident_item = format_ident!("{ident}_item"); + let ident_item_get = format_ident!("{ident}_item_get"); + + vquote! { + /// Get length of #ident. + fn #ident_len(&self) -> usize { + self.#ident.len() + } + } + + vquote! { + /// Get #ident item. + /// # Panic + /// Panics if `index` is out of bounds. + fn #ident_item(&self, index: usize) -> #generic_ty { + self.#ident[index] + } + } + + vquote! { + /// Get #ident item. + /// Returns `None` if `index` is out of bounds. + fn #ident_item_get(&self, index: usize) -> #generic_ty { + self.#ident.get(index).copied() + } + } + } + + fn generate(self, v: &mut Vec) { + if is_ast_enum_type_name(&type_name(self.generic_ty)) { + self.generate_as_enum(v); + } else { + self.generate_as_struct(v); + } + } +} + +fn generate_traversable_struct_method(_: &mut Vec, _: &Field) {} + +fn generate_traversable_enum_method(_: &mut Vec, _: &Field) {} + +// transformers + +fn transform_fields(fields: &Fields) -> Punctuated { + let Fields::Named(fields) = fields else { + panic!("`ast_node` attribute only works with named structure fields"); + }; + fields.named.iter().map(ToOwned::to_owned).map(transform_field).collect() +} + +fn transform_field(mut field: Field) -> Field { + field.ty = transform_type(field.ty); + field.attrs.clear(); + + field +} + +fn transform_variants(variants: &Punctuated) -> Punctuated { + variants.into_iter().map(ToOwned::to_owned).map(transform_variant).collect() +} + +fn transform_variant(mut variant: Variant) -> Variant { + let Fields::Unnamed(mut fields) = variant.fields else { + return variant; + }; + + fields.unnamed = fields.unnamed.into_iter().map(transform_field).collect(); + + variant.fields = Fields::Unnamed(fields); + variant.attrs.clear(); + variant +} + +fn transform_type(ty: Type) -> Type { + match ty { + Type::Path(ty) => transform_type_path(ty), + Type::Reference(ty) => transform_type_reference(ty), + _ => ty, + } +} + +fn transform_type_path(ty: TypePath) -> Type { + let ty = transform_generic_type(ty); + + Type::Path(ty) +} + +fn transform_type_reference(mut ty: TypeReference) -> Type { + let elem = transform_type(*ty.elem); + ty.elem = Box::from(elem); + + Type::Reference(ty) +} + +fn transform_generic_type(mut ty: TypePath) -> TypePath { + fn recreate_original_path(mut path: Path, ident: Ident, arguments: PathArguments) -> Path { + path.segments.push(PathSegment { ident, arguments }); + path + } + + fn recreate_original_type( + mut ty: TypePath, + ident: Ident, + arguments: PathArguments, + ) -> TypePath { + ty.path = recreate_original_path(ty.path, ident, arguments); + ty + } + + fn transform_args( + args: Punctuated, + ) -> Punctuated { + args.into_iter() + .map(|arg| match arg { + GenericArgument::Type(ty) => GenericArgument::Type(transform_type(ty)), + _ => arg, + }) + .collect() + } + + assert!(!ty.path.segments.is_empty()); + let seg = ty + .path + .segments + .pop() + .expect("Expected generic type with one or more path segments.") + .into_value(); + + match seg.arguments { + // as the rule of thumb; if a type has lifetimes we should transform it to a traversable type. + PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }) + if args.iter().any(|arg| matches!(arg, GenericArgument::Lifetime(_))) => + { + let path = if seg.ident == "Vec" { + parse_quote!(SharedVec) + } else if seg.ident == "Box" { + parse_quote!(SharedBox) + } else if !is_special_type_name(&seg.ident) { + let new_ident = format_ident!("{TRAVERSABLE}{}", seg.ident); + parse_quote!(#new_ident) + } else { + recreate_original_path(ty.path, seg.ident, PathArguments::None) + }; + + let args = transform_args(args); + + parse_quote!(#path <#args>) + } + PathArguments::AngleBracketed(angle_args @ AngleBracketedGenericArguments { .. }) => { + recreate_original_type( + ty, + seg.ident, + PathArguments::AngleBracketed(AngleBracketedGenericArguments { + args: transform_args(angle_args.args), + ..angle_args + }), + ) + } + PathArguments::Parenthesized(_) => { + panic!("`ast_node` does not support parenthesized types(eg. `Fn(u32) -> u32)`."); + } + PathArguments::None => recreate_original_type(ty, seg.ident, PathArguments::None), + } +} + +// fn transform_derive_attribute(attr: Attribute) -> Attribute { +// attr +// } + +fn is_special_type_name(ident: &Ident) -> bool { + ident == "Atom" + || ident == "RegExp" + || ident == "TemplateElementValue" + || ident == "IdentifierName" + || ident == "Modifiers" +} + +fn is_traversable_type_name(ident: &str) -> bool { + ident.starts_with(TRAVERSABLE) +} + +fn is_shared_type_name(ident: &str) -> bool { + ident.starts_with("Shared") +} + +fn is_ast_enum_type_name(ident: &str) -> bool { + if ident.len() <= TRAVERSABLE.len() { + return false; + } + let ident = &ident[TRAVERSABLE.len()..]; + matches! { + ident, + | "Statement" + } +} + +fn is_collection(ident: &str) -> bool { + ident == "Vec" +} + +fn type_name(ty: &Type) -> String { + fn type_path_name(ty: &TypePath) -> String { + assert!(!ty.path.segments.is_empty()); + let seg = &ty + .path + .segments + .last() + .expect("Expected generic type with one or more path segments."); + + // TODO: is there any way to get this as `&str`? + seg.ident.to_string() + } + + fn type_ref_name(ty: &TypeReference) -> String { + type_name(ty.elem.as_ref()) + } + + match ty { + Type::Path(ty) => type_path_name(ty), + Type::Reference(ty) => type_ref_name(ty), + _ => panic!("Unsupported type!"), + } +} + +fn type_generics(ty: &Type) -> Option<&AngleBracketedGenericArguments> { + fn type_path_generics(ty: &TypePath) -> Option<&AngleBracketedGenericArguments> { + assert!(!ty.path.segments.is_empty()); + let seg = &ty + .path + .segments + .last() + .expect("Expected generic type with one or more path segments."); + + match &seg.arguments { + PathArguments::AngleBracketed(args) => Some(args), + PathArguments::Parenthesized(_) => { + panic!("Parenthesized type arguments are not allowed with `ast_node` attribute.") + } + PathArguments::None => None, + } + } + + match ty { + Type::Path(ty) => type_path_generics(ty), + _ => panic!("Unsupported type!"), + } +} + +#[allow(dead_code)] +fn has_clone(attrs: &[Attribute]) -> bool { + attrs.iter().any(|attr| { + let args = attr.parse_args_with(Punctuated::::parse_terminated); + attr.path().is_ident("derive") + && args.is_ok_and(|args| args.iter().any(|arg| arg.path().is_ident("Clone"))) + }) +} + +struct NodeData<'a> { + ident: &'a Ident, + traversable: TokenStream2, +} diff --git a/crates/oxc_macros/src/lib.rs b/crates/oxc_macros/src/lib.rs index 9f3a1a1179517..ddb77e39dcf6c 100644 --- a/crates/oxc_macros/src/lib.rs +++ b/crates/oxc_macros/src/lib.rs @@ -1,6 +1,7 @@ use proc_macro::TokenStream; -use syn::parse_macro_input; +use syn::{parse_macro_input, Item}; +mod ast_node; mod declare_all_lint_rules; mod declare_oxc_lint; @@ -56,3 +57,9 @@ pub fn declare_all_lint_rules(input: TokenStream) -> TokenStream { let metadata = parse_macro_input!(input as declare_all_lint_rules::AllLintRulesMeta); declare_all_lint_rules::declare_all_lint_rules(metadata) } + +#[proc_macro_attribute] +pub fn ast_node(_args: TokenStream, input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as Item); + ast_node::ast_node(input).into() +} diff --git a/crates/oxc_minifier/src/compressor/ast_util.rs b/crates/oxc_minifier/src/compressor/ast_util.rs index d74ea5e1f30db..a4c6eed096a6c 100644 --- a/crates/oxc_minifier/src/compressor/ast_util.rs +++ b/crates/oxc_minifier/src/compressor/ast_util.rs @@ -5,9 +5,12 @@ use num_traits::{One, Zero}; use oxc_semantic::ReferenceFlag; use oxc_syntax::operator::{AssignmentOperator, LogicalOperator, UnaryOperator}; -use oxc_ast::ast::{ - match_expression, ArrayExpressionElement, BinaryExpression, Expression, NumericLiteral, - ObjectProperty, ObjectPropertyKind, PropertyKey, SpreadElement, UnaryExpression, +use oxc_ast::{ + ast::{ + match_expression, ArrayExpressionElement, BinaryExpression, Expression, NumericLiteral, + ObjectProperty, ObjectPropertyKind, PropertyKey, SpreadElement, UnaryExpression, + }, + dummy, }; /// Code ported from [closure-compiler](https://github.com/google/closure-compiler/blob/f3ce5ed8b630428e311fe9aa2e20d36560d975e2/src/com/google/javascript/jscomp/NodeUtil.java#LL836C6-L836C6) @@ -48,6 +51,7 @@ impl<'a, 'b> IsLiteralValue<'a, 'b> for ArrayExpressionElement<'a> { Self::SpreadElement(element) => element.is_literal_value(include_functions), match_expression!(Self) => self.to_expression().is_literal_value(include_functions), Self::Elision(_) => true, + Self::Dummy => dummy!(), } } } @@ -63,6 +67,7 @@ impl<'a, 'b> IsLiteralValue<'a, 'b> for ObjectPropertyKind<'a> { match self { Self::ObjectProperty(method) => method.is_literal_value(include_functions), Self::SpreadProperty(property) => property.is_literal_value(include_functions), + Self::Dummy => dummy!(), } } } @@ -79,6 +84,7 @@ impl<'a, 'b> IsLiteralValue<'a, 'b> for PropertyKey<'a> { match self { Self::StaticIdentifier(_) | Self::PrivateIdentifier(_) => false, match_expression!(Self) => self.to_expression().is_literal_value(include_functions), + Self::Dummy => dummy!(), } } } @@ -189,6 +195,7 @@ impl<'a, 'b> CheckForStateChange<'a, 'b> for ArrayExpressionElement<'a> { self.to_expression().check_for_state_change(check_for_new_objects) } Self::Elision(_) => false, + Self::Dummy => dummy!(), } } } @@ -200,6 +207,7 @@ impl<'a, 'b> CheckForStateChange<'a, 'b> for ObjectPropertyKind<'a> { Self::SpreadProperty(spread_element) => { spread_element.check_for_state_change(check_for_new_objects) } + Self::Dummy => dummy!(), } } } @@ -227,6 +235,7 @@ impl<'a, 'b> CheckForStateChange<'a, 'b> for PropertyKey<'a> { match_expression!(Self) => { self.to_expression().check_for_state_change(check_for_new_objects) } + Self::Dummy => dummy!(), } } } diff --git a/crates/oxc_module_lexer/src/lib.rs b/crates/oxc_module_lexer/src/lib.rs index 83d367d2accd1..99a6cf7ba41cd 100644 --- a/crates/oxc_module_lexer/src/lib.rs +++ b/crates/oxc_module_lexer/src/lib.rs @@ -2,12 +2,15 @@ //! //! * -use oxc_ast::visit::walk::{ - walk_export_all_declaration, walk_export_named_declaration, walk_import_declaration, - walk_import_expression, walk_meta_property, walk_module_declaration, walk_statement, -}; #[allow(clippy::wildcard_imports)] use oxc_ast::{ast::*, syntax_directed_operations::BoundNames, Visit}; +use oxc_ast::{ + dummy, + visit::walk::{ + walk_export_all_declaration, walk_export_named_declaration, walk_import_declaration, + walk_import_expression, walk_meta_property, walk_module_declaration, walk_statement, + }, +}; use oxc_span::{Atom, GetSpan}; #[derive(Debug, Clone)] @@ -223,10 +226,11 @@ impl<'a> Visit<'a> for ModuleLexer<'a> { ModuleExportName::Identifier(ident) => (ident.span.start, ident.span.end), // +1 -1 to remove the string quotes ModuleExportName::StringLiteral(s) => (s.span.start + 1, s.span.end - 1), + ModuleExportName::Dummy => dummy!(), }; ExportSpecifier { - n: s.exported.name().clone(), - ln: decl.source.is_none().then(|| s.local.name().clone()), + n: s.exported.as_atom(), + ln: decl.source.is_none().then(|| s.local.as_atom()), s: exported_start, e: exported_end, ls: Some(s.local.span().start), @@ -247,7 +251,7 @@ impl<'a> Visit<'a> for ModuleLexer<'a> { _ => None, }; self.exports.push(ExportSpecifier { - n: decl.exported.name().clone(), + n: decl.exported.as_atom(), ln: ln.map(|id| id.name.clone()), s: decl.exported.span().start, e: decl.exported.span().end, @@ -259,7 +263,7 @@ impl<'a> Visit<'a> for ModuleLexer<'a> { fn visit_export_all_declaration(&mut self, decl: &ExportAllDeclaration<'a>) { // export * as ns from 'foo' if let Some(exported) = &decl.exported { - let n = exported.name().clone(); + let n = exported.as_atom(); let s = exported.span().start; let e = exported.span().end; self.exports.push(ExportSpecifier { n: n.clone(), ln: None, s, e, ls: None, le: None }); diff --git a/crates/oxc_parser/src/js/binding.rs b/crates/oxc_parser/src/js/binding.rs index f284409113d22..0aa4bb8499aa6 100644 --- a/crates/oxc_parser/src/js/binding.rs +++ b/crates/oxc_parser/src/js/binding.rs @@ -1,5 +1,5 @@ use oxc_allocator::Box; -use oxc_ast::ast::*; +use oxc_ast::{ast::*, dummy}; use oxc_diagnostics::Result; use oxc_span::Span; @@ -143,6 +143,8 @@ impl<'a> ParserImpl<'a> { BindingPatternKind::ObjectPattern(pat) => &mut pat.span, BindingPatternKind::ArrayPattern(pat) => &mut pat.span, BindingPatternKind::AssignmentPattern(pat) => &mut pat.span, + // Ignore dummy nodes + BindingPatternKind::Dummy => return dummy!(), }; pat_span.end = span.end; } diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index 806d799e9204e..309007eb9f48a 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -330,7 +330,7 @@ impl<'a> ParserImpl<'a> { match self.cur_kind() { Kind::PrivateIdentifier => { let private_ident = self.parse_private_identifier(); - Ok((PropertyKey::PrivateIdentifier(self.ast.alloc(private_ident)), false)) + Ok((PropertyKey::PrivateIdentifier(private_ident), false)) } _ => self.parse_property_name(), } diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 7d90b6a261a16..8aa3beebd7930 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -83,13 +83,13 @@ impl<'a> ParserImpl<'a> { Ok(BindingIdentifier { span, name, symbol_id: Cell::default() }) } - pub(crate) fn parse_label_identifier(&mut self) -> Result> { + pub(crate) fn parse_label_identifier(&mut self) -> Result>> { if !self.cur_kind().is_label_identifier(self.ctx.has_yield(), self.ctx.has_await()) { return Err(self.unexpected()); } let (span, name) = self.parse_identifier_kind(Kind::Ident); self.check_identifier(span, &name); - Ok(LabelIdentifier { span, name }) + Ok(self.ast.alloc(LabelIdentifier { span, name })) } pub(crate) fn parse_identifier_name(&mut self) -> Result> { @@ -129,11 +129,11 @@ impl<'a> ParserImpl<'a> { /// `PrivateIdentifier` :: /// # `IdentifierName` /// # Panics - pub(crate) fn parse_private_identifier(&mut self) -> PrivateIdentifier<'a> { + pub(crate) fn parse_private_identifier(&mut self) -> Box<'a, PrivateIdentifier<'a>> { let span = self.start_span(); let name = Atom::from(self.cur_string()); self.bump_any(); - PrivateIdentifier { span: self.end_span(span), name } + self.ast.alloc(PrivateIdentifier { span: self.end_span(span), name }) } /// Section [Primary Expression](https://tc39.es/ecma262/#sec-primary-expression) @@ -372,7 +372,7 @@ impl<'a> ParserImpl<'a> { /// , /// Elision , pub(crate) fn parse_elision(&mut self) -> ArrayExpressionElement<'a> { - ArrayExpressionElement::Elision(Elision { span: self.cur_token().span() }) + ArrayExpressionElement::Elision(self.ast.alloc(Elision { span: self.cur_token().span() })) } /// Section [Template Literal](https://tc39.es/ecma262/#prod-TemplateLiteral) @@ -439,7 +439,7 @@ impl<'a> ParserImpl<'a> { if in_optional_chain { self.error(diagnostics::OptionalChainTaggedTemplate(quasi.span)); } - Ok(self.ast.tagged_template_expression(span, lhs, quasi, type_parameters)) + Ok(self.ast.tagged_template_expression(span, lhs, self.ast.alloc(quasi), type_parameters)) } pub(crate) fn parse_template_element(&mut self, tagged: bool) -> TemplateElement<'a> { diff --git a/crates/oxc_parser/src/js/function.rs b/crates/oxc_parser/src/js/function.rs index 572eb6c753ded..0477d79e9fb38 100644 --- a/crates/oxc_parser/src/js/function.rs +++ b/crates/oxc_parser/src/js/function.rs @@ -68,7 +68,7 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_formal_parameters( &mut self, params_kind: FormalParameterKind, - ) -> Result<(Option>, Box<'a, FormalParameters<'a>>)> { + ) -> Result<(Option>>, Box<'a, FormalParameters<'a>>)> { let span = self.start_span(); let list: FormalParameterList<'_> = FormalParameterList::parse(self)?; let formal_parameters = diff --git a/crates/oxc_parser/src/js/grammar.rs b/crates/oxc_parser/src/js/grammar.rs index 0c91e964a4dbb..2fb464c28dd1c 100644 --- a/crates/oxc_parser/src/js/grammar.rs +++ b/crates/oxc_parser/src/js/grammar.rs @@ -1,6 +1,6 @@ //! Cover Grammar for Destructuring Assignment -use oxc_ast::ast::*; +use oxc_ast::{ast::*, dummy}; use oxc_diagnostics::Result; use oxc_span::GetSpan; @@ -76,10 +76,9 @@ impl<'a> CoverGrammar<'a, ArrayExpression<'a>> for ArrayAssignmentTarget<'a> { } ArrayExpressionElement::SpreadElement(elem) => { if i == len - 1 { - rest = Some(AssignmentTargetRest { - span: elem.span, - target: AssignmentTarget::cover(elem.unbox().argument, p)?, - }); + let span = elem.span; + let target = AssignmentTarget::cover(elem.unbox().argument, p)?; + rest = Some(p.ast.alloc(AssignmentTargetRest { span, target })); if let Some(span) = expr.trailing_comma { p.error(diagnostics::BindingRestElementTrailingComma(span)); } @@ -88,6 +87,7 @@ impl<'a> CoverGrammar<'a, ArrayExpression<'a>> for ArrayAssignmentTarget<'a> { } } ArrayExpressionElement::Elision(_) => elements.push(None), + ArrayExpressionElement::Dummy => dummy!(), } } @@ -135,14 +135,14 @@ impl<'a> CoverGrammar<'a, ObjectExpression<'a>> for ObjectAssignmentTarget<'a> { } ObjectPropertyKind::SpreadProperty(spread) => { if i == len - 1 { - rest = Some(AssignmentTargetRest { - span: spread.span, - target: AssignmentTarget::cover(spread.unbox().argument, p)?, - }); + let span = spread.span; + let target = AssignmentTarget::cover(spread.unbox().argument, p)?; + rest = Some(p.ast.alloc(AssignmentTargetRest { span, target })); } else { return Err(diagnostics::SpreadLastElement(spread.span).into()); } } + ObjectPropertyKind::Dummy => dummy!(), } } @@ -156,7 +156,7 @@ impl<'a> CoverGrammar<'a, ObjectProperty<'a>> for AssignmentTargetProperty<'a> { let binding = match property.key { PropertyKey::StaticIdentifier(ident) => { let ident = ident.unbox(); - IdentifierReference::new(ident.span, ident.name) + p.ast.alloc(IdentifierReference::new(ident.span, ident.name)) } _ => return Err(p.unexpected()), }; diff --git a/crates/oxc_parser/src/js/list.rs b/crates/oxc_parser/src/js/list.rs index d3c75956ab488..e95cc5639b3ba 100644 --- a/crates/oxc_parser/src/js/list.rs +++ b/crates/oxc_parser/src/js/list.rs @@ -238,7 +238,7 @@ impl<'a> SeparatedList<'a> for SequenceExpressionList<'a> { pub struct FormalParameterList<'a> { pub elements: Vec<'a, FormalParameter<'a>>, pub rest: Option>>, - pub this_param: Option>, + pub this_param: Option>>, } impl<'a> SeparatedList<'a> for FormalParameterList<'a> { @@ -315,9 +315,12 @@ impl<'a> SeparatedList<'a> for AssertEntries<'a> { fn parse_element(&mut self, p: &mut ParserImpl<'a>) -> Result<()> { let span = p.start_span(); - let key = match p.cur_kind() { - Kind::Str => ImportAttributeKey::StringLiteral(p.parse_literal_string()?), - _ => ImportAttributeKey::Identifier(p.parse_identifier_name()?), + let key = if p.cur_kind() == Kind::Str { + let str_lit = p.parse_literal_string()?; + ImportAttributeKey::StringLiteral(p.ast.alloc(str_lit)) + } else { + let id = p.parse_identifier_name()?; + ImportAttributeKey::Identifier(p.ast.alloc(id)) }; if let Some(old_span) = self.keys.get(&key.as_atom()) { @@ -328,7 +331,7 @@ impl<'a> SeparatedList<'a> for AssertEntries<'a> { p.expect(Kind::Colon)?; let value = p.parse_literal_string()?; - let element = ImportAttribute { span: p.end_span(span), key, value }; + let element = ImportAttribute { span: p.end_span(span), key, value: p.ast.alloc(value) }; self.elements.push(element); Ok(()) } @@ -380,7 +383,19 @@ impl<'a> SeparatedList<'a> for ExportNamedSpecifiers<'a> { } let local = p.parse_module_export_name()?; - let exported = if p.eat(Kind::As) { p.parse_module_export_name()? } else { local.clone() }; + let exported = if p.eat(Kind::As) { + p.parse_module_export_name()? + } else { + match &local { + ModuleExportName::Identifier(id) => { + ModuleExportName::Identifier(p.ast.alloc((**id).clone())) + } + ModuleExportName::StringLiteral(str_lit) => { + ModuleExportName::StringLiteral(p.ast.alloc((**str_lit).clone())) + } + ModuleExportName::Dummy => ModuleExportName::Dummy, + } + }; let element = ExportSpecifier { span: p.end_span(specifier_span), local, exported, export_kind }; self.elements.push(element); diff --git a/crates/oxc_parser/src/js/module.rs b/crates/oxc_parser/src/js/module.rs index 53447faaa3bfe..ec5442658367e 100644 --- a/crates/oxc_parser/src/js/module.rs +++ b/crates/oxc_parser/src/js/module.rs @@ -1,5 +1,5 @@ use oxc_allocator::{Box, Vec}; -use oxc_ast::ast::*; +use oxc_ast::{ast::*, dummy}; use oxc_diagnostics::Result; use oxc_span::Span; @@ -107,9 +107,9 @@ impl<'a> ParserImpl<'a> { fn parse_import_default_specifier(&mut self) -> Result> { let span = self.start_span(); let local = self.parse_binding_identifier()?; - Ok(ImportDeclarationSpecifier::ImportDefaultSpecifier( - self.ast.alloc(ImportDefaultSpecifier { span: self.end_span(span), local }), - )) + Ok(ImportDeclarationSpecifier::ImportDefaultSpecifier(self.ast.alloc( + ImportDefaultSpecifier { span: self.end_span(span), local: self.ast.alloc(local) }, + ))) } // import * as name from "module-name" @@ -118,9 +118,9 @@ impl<'a> ParserImpl<'a> { self.bump_any(); // advance `*` self.expect(Kind::As)?; let local = self.parse_binding_identifier()?; - Ok(ImportDeclarationSpecifier::ImportNamespaceSpecifier( - self.ast.alloc(ImportNamespaceSpecifier { span: self.end_span(span), local }), - )) + Ok(ImportDeclarationSpecifier::ImportNamespaceSpecifier(self.ast.alloc( + ImportNamespaceSpecifier { span: self.end_span(span), local: self.ast.alloc(local) }, + ))) } // import { export1 , export2 as alias2 , [...] } from "module-name"; @@ -133,7 +133,7 @@ impl<'a> ParserImpl<'a> { } /// [Import Attributes](https://tc39.es/proposal-import-attributes) - fn parse_import_attributes(&mut self) -> Result>> { + fn parse_import_attributes(&mut self) -> Result>>> { let attributes_keyword = match self.cur_kind() { Kind::Assert if !self.cur_token().is_on_new_line => self.parse_identifier_name()?, Kind::With => self.parse_identifier_name()?, @@ -147,7 +147,11 @@ impl<'a> ParserImpl<'a> { let with_entries = AssertEntries::parse(self)?.elements; self.ctx = ctx; - Ok(Some(WithClause { span: self.end_span(span), attributes_keyword, with_entries })) + Ok(Some(self.ast.alloc(WithClause { + span: self.end_span(span), + attributes_keyword: self.ast.alloc(attributes_keyword), + with_entries, + }))) } pub(crate) fn parse_ts_export_assignment_declaration( @@ -172,7 +176,10 @@ impl<'a> ParserImpl<'a> { let id = self.parse_identifier_name()?; self.asi()?; - Ok(self.ast.alloc(TSNamespaceExportDeclaration { span: self.end_span(span), id })) + Ok(self.ast.alloc(TSNamespaceExportDeclaration { + span: self.end_span(span), + id: self.ast.alloc(id), + })) } /// [Exports](https://tc39.es/ecma262/#sec-exports) @@ -265,6 +272,7 @@ impl<'a> ParserImpl<'a> { )); } } + ModuleExportName::Dummy => dummy!(), } } } @@ -354,7 +362,7 @@ impl<'a> ParserImpl<'a> { decl } }; - let exported = ModuleExportName::Identifier(exported); + let exported = ModuleExportName::Identifier(self.ast.alloc(exported)); let span = self.end_span(span); Ok(self.ast.export_default_declaration(span, declaration, exported)) } @@ -411,12 +419,12 @@ impl<'a> ParserImpl<'a> { } else { let local = self.parse_binding_identifier()?; let imported = IdentifierName { span: local.span, name: local.name.clone() }; - (ModuleExportName::Identifier(imported), local) + (ModuleExportName::Identifier(self.ast.alloc(imported)), local) }; Ok(self.ast.alloc(ImportSpecifier { span: self.end_span(specifier_span), imported, - local, + local: self.ast.alloc(local), import_kind, })) } @@ -425,17 +433,17 @@ impl<'a> ParserImpl<'a> { // IdentifierName // StringLiteral pub(crate) fn parse_module_export_name(&mut self) -> Result> { - match self.cur_kind() { - Kind::Str => { - let literal = self.parse_literal_string()?; - // ModuleExportName : StringLiteral - // It is a Syntax Error if IsStringWellFormedUnicode(the SV of StringLiteral) is false. - if !literal.is_string_well_formed_unicode() { - self.error(diagnostics::ExportLoneSurrogate(literal.span)); - }; - Ok(ModuleExportName::StringLiteral(literal)) - } - _ => Ok(ModuleExportName::Identifier(self.parse_identifier_name()?)), + if self.cur_kind() == Kind::Str { + let literal = self.parse_literal_string()?; + // ModuleExportName : StringLiteral + // It is a Syntax Error if IsStringWellFormedUnicode(the SV of StringLiteral) is false. + if !literal.is_string_well_formed_unicode() { + self.error(diagnostics::ExportLoneSurrogate(literal.span)); + }; + Ok(ModuleExportName::StringLiteral(self.ast.alloc(literal))) + } else { + let id = self.parse_identifier_name()?; + Ok(ModuleExportName::Identifier(self.ast.alloc(id))) } } diff --git a/crates/oxc_parser/src/js/statement.rs b/crates/oxc_parser/src/js/statement.rs index 8a4eff9e5f588..32e7f63ecc327 100644 --- a/crates/oxc_parser/src/js/statement.rs +++ b/crates/oxc_parser/src/js/statement.rs @@ -151,7 +151,11 @@ impl<'a> ParserImpl<'a> { if self.eat(Kind::Colon) { let label = LabelIdentifier { span: ident.span, name: ident.name.clone() }; let body = self.parse_statement_list_item(StatementContext::Label)?; - return Ok(self.ast.labeled_statement(self.end_span(span), label, body)); + return Ok(self.ast.labeled_statement( + self.end_span(span), + self.ast.alloc(label), + body, + )); } } self.parse_expression_statement(span, expr) diff --git a/crates/oxc_parser/src/jsx/mod.rs b/crates/oxc_parser/src/jsx/mod.rs index a8a4faa649a65..78d7a514d13b8 100644 --- a/crates/oxc_parser/src/jsx/mod.rs +++ b/crates/oxc_parser/src/jsx/mod.rs @@ -144,7 +144,7 @@ impl<'a> ParserImpl<'a> { .map(JSXElementName::MemberExpression); } - Ok(JSXElementName::Identifier(self.ast.alloc(identifier))) + Ok(JSXElementName::Identifier(identifier)) } /// `JSXMemberExpression` : @@ -153,10 +153,10 @@ impl<'a> ParserImpl<'a> { fn parse_jsx_member_expression( &mut self, span: Span, - object: JSXIdentifier<'a>, + object: Box<'a, JSXIdentifier<'a>>, ) -> Result>> { let mut span = span; - let mut object = JSXMemberExpressionObject::Identifier(self.ast.alloc(object)); + let mut object = JSXMemberExpressionObject::Identifier(object); let mut property = None; while self.eat(Kind::Dot) && !self.at(Kind::Eof) { @@ -337,7 +337,7 @@ impl<'a> ParserImpl<'a> { ))); } - Ok(JSXAttributeName::Identifier(self.ast.alloc(identifier))) + Ok(JSXAttributeName::Identifier(identifier)) } fn parse_jsx_attribute_value(&mut self) -> Result> { @@ -364,7 +364,7 @@ impl<'a> ParserImpl<'a> { /// `IdentifierStart` /// `JSXIdentifier` `IdentifierPart` /// `JSXIdentifier` [no `WhiteSpace` or Comment here] - - fn parse_jsx_identifier(&mut self) -> Result> { + fn parse_jsx_identifier(&mut self) -> Result>> { let span = self.start_span(); if !self.at(Kind::Ident) && !self.cur_kind().is_all_keyword() { return Err(self.unexpected()); diff --git a/crates/oxc_parser/src/ts/list.rs b/crates/oxc_parser/src/ts/list.rs index 75560eba69799..c8875ae37e8ce 100644 --- a/crates/oxc_parser/src/ts/list.rs +++ b/crates/oxc_parser/src/ts/list.rs @@ -62,7 +62,7 @@ impl<'a> SeparatedList<'a> for TSTupleElementList<'a> { type_annotation: TSType::TSNamedTupleMember(p.ast.alloc(TSNamedTupleMember { span: p.end_span(member_span), element_type, - label, + label: p.ast.alloc(label), optional: false, // A tuple member cannot be both optional and rest. (TS5085) })), }))); @@ -75,7 +75,12 @@ impl<'a> SeparatedList<'a> for TSTupleElementList<'a> { let element_type = p.parse_ts_type()?; self.elements.push(TSTupleElement::TSNamedTupleMember(p.ast.alloc( - TSNamedTupleMember { span: p.end_span(span), element_type, label, optional }, + TSNamedTupleMember { + span: p.end_span(span), + element_type, + label: p.ast.alloc(label), + optional, + }, ))); return Ok(()); @@ -195,9 +200,12 @@ impl<'a> SeparatedList<'a> for TSImportAttributeList<'a> { fn parse_element(&mut self, p: &mut ParserImpl<'a>) -> Result<()> { let span = p.start_span(); - let name = match p.cur_kind() { - Kind::Str => TSImportAttributeName::StringLiteral(p.parse_literal_string()?), - _ => TSImportAttributeName::Identifier(p.parse_identifier_name()?), + let name = if p.cur_kind() == Kind::Str { + let str_lit = p.parse_literal_string()?; + TSImportAttributeName::StringLiteral(p.ast.alloc(str_lit)) + } else { + let id = p.parse_identifier_name()?; + TSImportAttributeName::Identifier(p.ast.alloc(id)) }; p.expect(Kind::Colon)?; diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index a4c732118a38d..209a50d75e17c 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -240,10 +240,13 @@ impl<'a> ParserImpl<'a> { kind: TSModuleDeclarationKind, modifiers: Modifiers<'a>, ) -> Result>> { - let id = match self.cur_kind() { - Kind::Str => self.parse_literal_string().map(TSModuleDeclarationName::StringLiteral), - _ => self.parse_identifier_name().map(TSModuleDeclarationName::Identifier), - }?; + let id = if self.cur_kind() == Kind::Str { + let str_lit = self.parse_literal_string()?; + TSModuleDeclarationName::StringLiteral(self.ast.alloc(str_lit)) + } else { + let id = self.parse_identifier_name()?; + TSModuleDeclarationName::Identifier(self.ast.alloc(id)) + }; let body = if self.eat(Kind::Dot) { let span = self.start_span(); @@ -384,7 +387,7 @@ impl<'a> ParserImpl<'a> { self.expect(Kind::RParen)?; self.ast.ts_module_reference_external_module_reference(TSExternalModuleReference { span: self.end_span(reference_span), - expression, + expression: self.ast.alloc(expression), }) } else { let node = self.parse_ts_type_name()?; @@ -401,7 +404,7 @@ impl<'a> ParserImpl<'a> { )) } - pub(crate) fn parse_ts_this_parameter(&mut self) -> Result> { + pub(crate) fn parse_ts_this_parameter(&mut self) -> Result>> { let span = self.start_span(); let this = { diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index d8d34140dfdef..801dc834c9109 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -500,7 +500,7 @@ impl<'a> ParserImpl<'a> { left = TSTypeName::QualifiedName(self.ast.alloc(TSQualifiedName { span: self.end_span(span), left, - right, + right: self.ast.alloc(right), })); } Ok(left) @@ -793,7 +793,7 @@ impl<'a> ParserImpl<'a> { }) } - fn parse_ts_import_attributes(&mut self) -> Result> { + fn parse_ts_import_attributes(&mut self) -> Result>> { let span = self.start_span(); // { with: self.expect(Kind::LCurly)?; @@ -801,7 +801,8 @@ impl<'a> ParserImpl<'a> { self.expect(Kind::Colon)?; let elements = TSImportAttributeList::parse(self)?.elements; self.expect(Kind::RCurly)?; - Ok(TSImportAttributes { span, elements }) + + Ok(self.ast.alloc(TSImportAttributes { span, elements })) } fn parse_ts_constructor_type(&mut self) -> Result> { diff --git a/crates/oxc_prettier/src/format/class.rs b/crates/oxc_prettier/src/format/class.rs index bd520e564d4df..b3969fd2b1a91 100644 --- a/crates/oxc_prettier/src/format/class.rs +++ b/crates/oxc_prettier/src/format/class.rs @@ -1,4 +1,4 @@ -use oxc_ast::ast::*; +use oxc_ast::{ast::*, dummy}; use oxc_span::GetSpan; use crate::{ @@ -242,5 +242,6 @@ fn should_print_semicolon_after_class_property<'a>( false } + ClassElement::Dummy => dummy!(), } } diff --git a/crates/oxc_prettier/src/format/function_parameters.rs b/crates/oxc_prettier/src/format/function_parameters.rs index 738f666734d38..f2316be86e512 100644 --- a/crates/oxc_prettier/src/format/function_parameters.rs +++ b/crates/oxc_prettier/src/format/function_parameters.rs @@ -1,4 +1,4 @@ -use oxc_ast::{ast::*, AstKind}; +use oxc_ast::{ast::*, dummy, AstKind}; use crate::{ comments::CommentFlags, @@ -54,6 +54,7 @@ pub(super) fn should_hug_the_only_function_parameter( _ => false, } } + BindingPatternKind::Dummy => dummy!(), } } diff --git a/crates/oxc_prettier/src/format/mod.rs b/crates/oxc_prettier/src/format/mod.rs index 46021249ac403..0a38a97a71ce9 100644 --- a/crates/oxc_prettier/src/format/mod.rs +++ b/crates/oxc_prettier/src/format/mod.rs @@ -27,7 +27,7 @@ mod ternary; use std::borrow::Cow; use oxc_allocator::{Box, Vec}; -use oxc_ast::{ast::*, AstKind}; +use oxc_ast::{ast::*, dummy, AstKind}; use oxc_span::GetSpan; use oxc_syntax::identifier::is_identifier_name; @@ -124,6 +124,7 @@ impl<'a> Format<'a> for Statement<'a> { Self::WithStatement(stmt) => stmt.format(p), match_module_declaration!(Self) => self.to_module_declaration().format(p), match_declaration!(Self) => self.to_declaration().format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -236,6 +237,7 @@ impl<'a> Format<'a> for ForStatementInit<'a> { ForStatementInit::VariableDeclaration(v) => v.format(p), match_expression!(ForStatementInit) => self.to_expression().format(p), ForStatementInit::UsingDeclaration(v) => v.format(p), + ForStatementInit::Dummy => dummy!(unreachable), } } } @@ -282,6 +284,7 @@ impl<'a> Format<'a> for ForStatementLeft<'a> { ForStatementLeft::VariableDeclaration(v) => v.format(p), match_assignment_target!(ForStatementLeft) => self.to_assignment_target().format(p), ForStatementLeft::UsingDeclaration(v) => v.format(p), + ForStatementLeft::Dummy => dummy!(unreachable), } } } @@ -567,6 +570,7 @@ impl<'a> Format<'a> for Declaration<'a> { Self::TSEnumDeclaration(decl) => decl.format(p), Self::TSModuleDeclaration(decl) => decl.format(p), Self::TSImportEqualsDeclaration(decl) => decl.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -688,6 +692,7 @@ impl<'a> Format<'a> for TSType<'a> { TSType::TSUnionType(v) => v.format(p), TSType::JSDocNullableType(v) => v.format(p), TSType::JSDocUnknownType(v) => v.format(p), + TSType::Dummy => dummy!(unreachable), } } } @@ -841,6 +846,7 @@ impl<'a> Format<'a> for TSLiteralType<'a> { TSLiteral::StringLiteral(v) => v.format(p), TSLiteral::TemplateLiteral(v) => v.format(p), TSLiteral::UnaryExpression(v) => v.format(p), + TSLiteral::Dummy => dummy!(unreachable), } } } @@ -991,6 +997,7 @@ impl<'a> Format<'a> for TSModuleReference<'a> { TSModuleReference::IdentifierReference(it) => format!(p, it), TSModuleReference::QualifiedName(it) => format!(p, it), TSModuleReference::ExternalModuleReference(v) => v.format(p), + TSModuleReference::Dummy => dummy!(unreachable), } } } @@ -1000,6 +1007,7 @@ impl<'a> Format<'a> for TSTypeName<'a> { match self { TSTypeName::IdentifierReference(it) => format!(p, it), TSTypeName::QualifiedName(it) => format!(p, it), + TSTypeName::Dummy => dummy!(unreachable), } } } @@ -1106,6 +1114,7 @@ impl<'a> Format<'a> for ImportDeclarationSpecifier<'a> { Self::ImportSpecifier(specifier) => specifier.format(p), Self::ImportDefaultSpecifier(specifier) => specifier.format(p), Self::ImportNamespaceSpecifier(specifier) => specifier.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1156,6 +1165,7 @@ impl<'a> Format<'a> for ImportAttributeKey<'a> { match self { Self::Identifier(ident) => ident.format(p), Self::StringLiteral(literal) => literal.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1205,6 +1215,7 @@ impl<'a> Format<'a> for ModuleExportName<'a> { match self { Self::Identifier(ident) => ident.format(p), Self::StringLiteral(literal) => literal.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1234,6 +1245,7 @@ impl<'a> Format<'a> for ExportDefaultDeclarationKind<'a> { Self::ClassDeclaration(decl) => decl.format(p), Self::TSInterfaceDeclaration(decl) => decl.format(p), Self::TSEnumDeclaration(decl) => decl.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1281,6 +1293,7 @@ impl<'a> Format<'a> for Expression<'a> { Self::TSTypeAssertion(expr) => expr.expression.format(p), Self::TSNonNullExpression(expr) => expr.expression.format(p), Self::TSInstantiationExpression(expr) => expr.expression.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1440,6 +1453,7 @@ impl<'a> Format<'a> for MemberExpression<'a> { Self::ComputedMemberExpression(expr) => expr.format(p), Self::StaticMemberExpression(expr) => expr.format(p), Self::PrivateFieldExpression(expr) => expr.format(p), + Self::Dummy => dummy!(unreachable), } }) } @@ -1498,6 +1512,7 @@ impl<'a> Format<'a> for Argument<'a> { match self { match_expression!(Self) => self.to_expression().format(p), Self::SpreadElement(expr) => expr.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1508,6 +1523,7 @@ impl<'a> Format<'a> for ArrayExpressionElement<'a> { Self::SpreadElement(expr) => expr.format(p), match_expression!(Self) => self.to_expression().format(p), Self::Elision(elision) => Doc::Str(""), + Self::Dummy => dummy!(unreachable), } } } @@ -1537,6 +1553,7 @@ impl<'a> Format<'a> for ObjectPropertyKind<'a> { match self { ObjectPropertyKind::ObjectProperty(prop) => prop.format(p), ObjectPropertyKind::SpreadProperty(prop) => prop.format(p), + ObjectPropertyKind::Dummy => dummy!(unreachable), } } } @@ -1611,6 +1628,7 @@ impl<'a> Format<'a> for PropertyKey<'a> { PropertyKey::StaticIdentifier(ident) => ident.format(p), PropertyKey::PrivateIdentifier(ident) => ident.format(p), match_expression!(PropertyKey) => self.to_expression().format(p), + PropertyKey::Dummy => dummy!(unreachable), }; parts.push(doc); parts.push(ss!("]")); @@ -1626,6 +1644,7 @@ impl<'a> Format<'a> for PropertyKey<'a> { property::is_property_key_has_quote(&p.key) } ObjectPropertyKind::SpreadProperty(_) => false, + ObjectPropertyKind::Dummy => dummy!(unreachable), }), Some(AstKind::ClassBody(a)) => a.body.iter().any(|x| match x { ClassElement::PropertyDefinition(p) => { @@ -1673,6 +1692,7 @@ impl<'a> Format<'a> for PropertyKey<'a> { array!(p, ss!("["), ident.format(p), ss!("]")) } match_expression!(PropertyKey) => self.to_expression().format(p), + PropertyKey::Dummy => dummy!(unreachable), } }) } @@ -1796,6 +1816,7 @@ impl<'a> Format<'a> for AssignmentTarget<'a> { match self { match_simple_assignment_target!(Self) => self.to_simple_assignment_target().format(p), match_assignment_target_pattern!(Self) => self.to_assignment_target_pattern().format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1809,6 +1830,7 @@ impl<'a> Format<'a> for SimpleAssignmentTarget<'a> { Self::TSSatisfiesExpression(expr) => expr.expression.format(p), Self::TSNonNullExpression(expr) => expr.expression.format(p), Self::TSTypeAssertion(expr) => expr.expression.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1818,6 +1840,7 @@ impl<'a> Format<'a> for AssignmentTargetPattern<'a> { match self { Self::ArrayAssignmentTarget(target) => target.format(p), Self::ObjectAssignmentTarget(target) => target.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1835,6 +1858,7 @@ impl<'a> Format<'a> for AssignmentTargetMaybeDefault<'a> { self.to_assignment_target().format(p) } AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(v) => v.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1856,6 +1880,7 @@ impl<'a> Format<'a> for AssignmentTargetProperty<'a> { match self { Self::AssignmentTargetPropertyIdentifier(ident) => ident.format(p), Self::AssignmentTargetPropertyProperty(prop) => prop.format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -1990,6 +2015,7 @@ impl<'a> Format<'a> for ChainElement<'a> { match self { Self::CallExpression(expr) => expr.format(p), match_member_expression!(Self) => self.to_member_expression().format(p), + Self::Dummy => dummy!(unreachable), } } } @@ -2031,6 +2057,7 @@ impl<'a> Format<'a> for ClassElement<'a> { ClassElement::PropertyDefinition(c) => c.format(p), ClassElement::AccessorProperty(c) => c.format(p), ClassElement::TSIndexSignature(c) => c.format(p), + ClassElement::Dummy => dummy!(unreachable), } } } @@ -2212,6 +2239,7 @@ impl<'a> Format<'a> for BindingPattern<'a> { BindingPatternKind::ObjectPattern(ref pattern) => pattern.format(p), BindingPatternKind::ArrayPattern(ref pattern) => pattern.format(p), BindingPatternKind::AssignmentPattern(ref pattern) => pattern.format(p), + BindingPatternKind::Dummy => dummy!(unreachable), }); if let Some(typ) = &self.type_annotation { parts.push(array![p, ss!(": "), typ.type_annotation.format(p)]); @@ -2340,6 +2368,7 @@ impl<'a> Format<'a> for TSSignature<'a> { TSSignature::TSCallSignatureDeclaration(it) => it.format(p), TSSignature::TSConstructSignatureDeclaration(it) => it.format(p), TSSignature::TSMethodSignature(it) => it.format(p), + TSSignature::Dummy => dummy!(unreachable), } } } diff --git a/crates/oxc_prettier/src/format/module.rs b/crates/oxc_prettier/src/format/module.rs index 428f6a9c02ff3..9e8641697b26b 100644 --- a/crates/oxc_prettier/src/format/module.rs +++ b/crates/oxc_prettier/src/format/module.rs @@ -28,6 +28,7 @@ pub(super) fn print_export_declaration<'a>( ModuleDeclaration::ExportNamedDeclaration(decl) => decl.format(p), ModuleDeclaration::TSExportAssignment(decl) => decl.format(p), ModuleDeclaration::TSNamespaceExportDeclaration(decl) => decl.format(p), + ModuleDeclaration::Dummy => Doc::Str("Dummy ModuleDeclaration"), }); if let Some(source) = decl.source() { @@ -61,7 +62,8 @@ fn print_semicolon_after_export_declaration<'a>( ExportDefaultDeclarationKind::FunctionDeclaration(_) | ExportDefaultDeclarationKind::ClassDeclaration(_) | ExportDefaultDeclarationKind::TSInterfaceDeclaration(_) - | ExportDefaultDeclarationKind::TSEnumDeclaration(_) => None, + | ExportDefaultDeclarationKind::TSEnumDeclaration(_) + | ExportDefaultDeclarationKind::Dummy => None, }, ModuleDeclaration::ExportAllDeclaration(_) | ModuleDeclaration::ExportNamedDeclaration(_) diff --git a/crates/oxc_prettier/src/needs_parens.rs b/crates/oxc_prettier/src/needs_parens.rs index 1e5e002eabb6e..ea59ab796c139 100644 --- a/crates/oxc_prettier/src/needs_parens.rs +++ b/crates/oxc_prettier/src/needs_parens.rs @@ -591,7 +591,8 @@ impl<'a> Prettier<'a> { Self::starts_with_no_lookahead_token(&e.expression, span) } AssignmentTarget::ArrayAssignmentTarget(_) - | AssignmentTarget::ObjectAssignmentTarget(_) => false, + | AssignmentTarget::ObjectAssignmentTarget(_) + | AssignmentTarget::Dummy => false, }, match_member_expression!(Expression) => { Self::starts_with_no_lookahead_token(e.to_member_expression().object(), span) @@ -636,6 +637,7 @@ impl<'a> Prettier<'a> { SimpleAssignmentTarget::TSTypeAssertion(e) => { Self::starts_with_no_lookahead_token(&e.expression, span) } + SimpleAssignmentTarget::Dummy => false, } } Expression::SequenceExpression(e) => e @@ -655,6 +657,7 @@ impl<'a> Prettier<'a> { ChainElement::PrivateFieldExpression(e) => { Self::starts_with_no_lookahead_token(&e.object, span) } + ChainElement::Dummy => false, }, Expression::TSSatisfiesExpression(e) => { Self::starts_with_no_lookahead_token(&e.expression, span) diff --git a/crates/oxc_semantic/src/binder.rs b/crates/oxc_semantic/src/binder.rs index f6a0494fcece1..4d9b1f71e1ebb 100644 --- a/crates/oxc_semantic/src/binder.rs +++ b/crates/oxc_semantic/src/binder.rs @@ -5,6 +5,7 @@ use std::borrow::Cow; #[allow(clippy::wildcard_imports)] use oxc_ast::ast::*; use oxc_ast::{ + dummy, syntax_directed_operations::{BoundNames, IsSimpleParameterList}, AstKind, }; @@ -343,6 +344,7 @@ impl<'a> Binder for TSEnumMember<'a> { TSEnumMemberName::StaticStringLiteral(s) => Cow::Borrowed(s.value.as_str()), TSEnumMemberName::StaticNumericLiteral(n) => Cow::Owned(n.value.to_string()), match_expression!(TSEnumMemberName) => panic!("TODO: implement"), + TSEnumMemberName::Dummy => dummy!(panic), }; builder.declare_symbol( self.span, @@ -364,7 +366,7 @@ impl<'a> Binder for TSModuleDeclaration<'a> { }; builder.declare_symbol( self.span, - self.id.name(), + self.id.as_atom().as_str(), SymbolFlags::NameSpaceModule | ambient, SymbolFlags::None, ); diff --git a/crates/oxc_semantic/src/builder.rs b/crates/oxc_semantic/src/builder.rs index 00bbe64fe99d8..b4cb1e3e7ba65 100644 --- a/crates/oxc_semantic/src/builder.rs +++ b/crates/oxc_semantic/src/builder.rs @@ -2,6 +2,7 @@ use std::{cell::RefCell, path::PathBuf, rc::Rc, sync::Arc}; +use oxc_ast::dummy; #[allow(clippy::wildcard_imports)] use oxc_ast::{ast::*, AstKind, Trivias, Visit}; use oxc_diagnostics::Error; @@ -837,6 +838,7 @@ impl<'a> Visit<'a> for SemanticBuilder<'a> { self.visit_variable_declaration(decl); } match_expression!(ForStatementInit) => self.visit_expression(init.to_expression()), + ForStatementInit::Dummy => dummy!(), } self.leave_node(kind); } @@ -1741,7 +1743,7 @@ impl<'a> SemanticBuilder<'a> { let symbol_id = self .scope .get_bindings(self.current_scope_id) - .get(module_declaration.id.name().as_str()); + .get(module_declaration.id.as_atom().as_str()); self.namespace_stack.push(*symbol_id.unwrap()); self.in_type_definition = true; } diff --git a/crates/oxc_semantic/src/checker/javascript.rs b/crates/oxc_semantic/src/checker/javascript.rs index bd6a44b05d352..db83d22b3186e 100644 --- a/crates/oxc_semantic/src/checker/javascript.rs +++ b/crates/oxc_semantic/src/checker/javascript.rs @@ -1,3 +1,4 @@ +use oxc_ast::dummy; #[allow(clippy::wildcard_imports)] use oxc_ast::{ ast::*, @@ -485,6 +486,7 @@ fn check_module_declaration<'a>( | ModuleDeclaration::ExportNamedDeclaration(_) | ModuleDeclaration::TSExportAssignment(_) | ModuleDeclaration::TSNamespaceExportDeclaration(_) => "export statement", + ModuleDeclaration::Dummy => dummy!(panic), }; let start = decl.span().start; let span = Span::new(start, start + 6); diff --git a/crates/oxc_semantic/src/module_record/builder.rs b/crates/oxc_semantic/src/module_record/builder.rs index 039609cf9e1a8..aed418dd341ec 100644 --- a/crates/oxc_semantic/src/module_record/builder.rs +++ b/crates/oxc_semantic/src/module_record/builder.rs @@ -1,5 +1,6 @@ use std::path::PathBuf; +use oxc_ast::dummy; #[allow(clippy::wildcard_imports)] use oxc_ast::{ast::*, syntax_directed_operations::BoundNames}; use oxc_span::{CompactStr, GetSpan, Span}; @@ -166,6 +167,7 @@ impl ModuleRecordBuilder { } ModuleDeclaration::TSExportAssignment(_) | ModuleDeclaration::TSNamespaceExportDeclaration(_) => { /* noop */ } + ModuleDeclaration::Dummy => dummy!(), } } @@ -177,7 +179,7 @@ impl ModuleRecordBuilder { let (import_name, local_name, is_type) = match specifier { ImportDeclarationSpecifier::ImportSpecifier(specifier) => ( ImportImportName::Name(NameSpan::new( - specifier.imported.name().to_compact_str(), + specifier.imported.as_atom().to_compact_str(), specifier.imported.span(), )), NameSpan::new(specifier.local.name.to_compact_str(), specifier.local.span), @@ -193,6 +195,8 @@ impl ModuleRecordBuilder { NameSpan::new(specifier.local.name.to_compact_str(), specifier.local.span), decl.import_kind.is_type(), ), + // Ignore dummy nodes + ImportDeclarationSpecifier::Dummy => continue, }; self.add_import_entry(ImportEntry { module_request: module_request.clone(), @@ -219,7 +223,7 @@ impl ModuleRecordBuilder { .map_or(ExportImportName::AllButDefault, |_| ExportImportName::All), export_name: decl.exported.as_ref().map_or(ExportExportName::Null, |exported_name| { ExportExportName::Name(NameSpan::new( - exported_name.name().to_compact_str(), + exported_name.as_atom().to_compact_str(), exported_name.span(), )) }), @@ -228,7 +232,7 @@ impl ModuleRecordBuilder { }; self.add_export_entry(export_entry); if let Some(exported_name) = &decl.exported { - self.add_export_binding(exported_name.name().to_compact_str(), exported_name.span()); + self.add_export_binding(exported_name.as_atom().to_compact_str(), exported_name.span()); } self.add_module_request( &module_request, @@ -251,6 +255,7 @@ impl ModuleRecordBuilder { ExportDefaultDeclarationKind::ClassDeclaration(class) => class.id.as_ref(), ExportDefaultDeclarationKind::TSInterfaceDeclaration(_) | ExportDefaultDeclarationKind::TSEnumDeclaration(_) => return, + ExportDefaultDeclarationKind::Dummy => return dummy!(), }; let export_entry = ExportEntry { export_name: ExportExportName::Default(exported_name.span()), @@ -308,12 +313,12 @@ impl ModuleRecordBuilder { for specifier in &decl.specifiers { let export_name = ExportExportName::Name(NameSpan::new( - specifier.exported.name().to_compact_str(), + specifier.exported.as_atom().to_compact_str(), specifier.exported.span(), )); let import_name = if module_request.is_some() { ExportImportName::Name(NameSpan::new( - specifier.local.name().to_compact_str(), + specifier.local.as_atom().to_compact_str(), specifier.local.span(), )) } else { @@ -323,7 +328,7 @@ impl ModuleRecordBuilder { ExportLocalName::Null } else { ExportLocalName::Name(NameSpan::new( - specifier.local.name().to_compact_str(), + specifier.local.as_atom().to_compact_str(), specifier.local.span(), )) }; @@ -336,7 +341,7 @@ impl ModuleRecordBuilder { }; self.add_export_entry(export_entry); self.add_export_binding( - specifier.exported.name().to_compact_str(), + specifier.exported.as_atom().to_compact_str(), specifier.exported.span(), ); } diff --git a/crates/oxc_semantic/tests/util/class_tester.rs b/crates/oxc_semantic/tests/util/class_tester.rs index fca21516257ac..a7be2f806d06e 100644 --- a/crates/oxc_semantic/tests/util/class_tester.rs +++ b/crates/oxc_semantic/tests/util/class_tester.rs @@ -15,7 +15,7 @@ impl<'a> ClassTester<'a> { let class_id = semantic.classes().iter_enumerated().find_map(|(class_id, ast_node_id)| { let kind = semantic.nodes().kind(*ast_node_id); if let AstKind::Class(class) = kind { - if class.id.clone().is_some_and(|id| id.name == name) { + if class.id.as_deref().is_some_and(|id| id.name == name) { return Some(class_id); }; } diff --git a/crates/oxc_span/Cargo.toml b/crates/oxc_span/Cargo.toml index baa3282bbb713..c0c08332cfaac 100644 --- a/crates/oxc_span/Cargo.toml +++ b/crates/oxc_span/Cargo.toml @@ -22,6 +22,8 @@ doctest = false miette = { workspace = true } compact_str = { workspace = true } +layout_inspect = { workspace = true, features = ["unique_names"] } + tsify = { workspace = true, optional = true } wasm-bindgen = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"], optional = true } diff --git a/crates/oxc_span/src/atom.rs b/crates/oxc_span/src/atom.rs index 9c28b5cfc3982..68f2e90b42d06 100644 --- a/crates/oxc_span/src/atom.rs +++ b/crates/oxc_span/src/atom.rs @@ -19,7 +19,7 @@ pub const MAX_INLINE_LEN: usize = 16; /// /// Use [CompactStr] with [Atom::to_compact_str] or [Atom::into_compact_str] for the /// lifetimeless form. -#[derive(Clone, Eq)] +#[derive(Clone, Eq, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", serde(transparent))] pub struct Atom<'a>(&'a str); diff --git a/crates/oxc_span/src/source_type.rs b/crates/oxc_span/src/source_type.rs index 9c320e5173c78..875d0c6a66d1a 100644 --- a/crates/oxc_span/src/source_type.rs +++ b/crates/oxc_span/src/source_type.rs @@ -9,7 +9,7 @@ use serde::Serialize; use tsify::Tsify; /// Source Type for JavaScript vs TypeScript / Script vs Module / JSX -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub struct SourceType { @@ -28,7 +28,7 @@ pub struct SourceType { } /// JavaScript or TypeScript -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "lowercase"))] pub enum Language { @@ -39,7 +39,7 @@ pub enum Language { } /// Script or Module -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub enum ModuleKind { @@ -48,7 +48,7 @@ pub enum ModuleKind { } /// JSX for JavaScript and TypeScript -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[cfg_attr(feature = "serialize", serde(rename_all = "camelCase"))] pub enum LanguageVariant { diff --git a/crates/oxc_span/src/span.rs b/crates/oxc_span/src/span.rs index 668f0e1c555e0..2d4863876c361 100644 --- a/crates/oxc_span/src/span.rs +++ b/crates/oxc_span/src/span.rs @@ -17,7 +17,7 @@ pub const SPAN: Span = Span::new(0, 0); /// See the [`text-size`](https://docs.rs/text-size) crate for details. /// Utility methods can be copied from the `text-size` crate if they are needed. /// NOTE: `u32` is sufficient for "all" reasonable programs. Larger than u32 is a 4GB JS file. -#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] #[non_exhaustive] // disallow struct expression constructor `Span {}` pub struct Span { diff --git a/crates/oxc_syntax/Cargo.toml b/crates/oxc_syntax/Cargo.toml index e668284e1112d..bb4a397c5fd48 100644 --- a/crates/oxc_syntax/Cargo.toml +++ b/crates/oxc_syntax/Cargo.toml @@ -28,7 +28,10 @@ rustc-hash = { workspace = true } dashmap = { workspace = true } phf = { workspace = true, features = ["macros"] } -ryu-js = { workspace = true, optional = true } +ryu-js = { workspace = true, optional = true } + +layout_inspect = { workspace = true, features = ["unique_names"] } + serde = { workspace = true, features = ["derive"], optional = true } tsify = { workspace = true, optional = true } wasm-bindgen = { workspace = true, optional = true } diff --git a/crates/oxc_syntax/src/number.rs b/crates/oxc_syntax/src/number.rs index d2749641e4adb..0dc11fe3ee150 100644 --- a/crates/oxc_syntax/src/number.rs +++ b/crates/oxc_syntax/src/number.rs @@ -1,4 +1,4 @@ -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] pub enum NumberBase { Float, Decimal, @@ -13,7 +13,7 @@ impl NumberBase { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] pub enum BigintBase { Decimal, Binary, diff --git a/crates/oxc_syntax/src/operator.rs b/crates/oxc_syntax/src/operator.rs index 184922b7aa980..47b9fe8941e43 100644 --- a/crates/oxc_syntax/src/operator.rs +++ b/crates/oxc_syntax/src/operator.rs @@ -8,7 +8,7 @@ use tsify::Tsify; use crate::precedence::{GetPrecedence, Precedence}; -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum AssignmentOperator { #[cfg_attr(feature = "serialize", serde(rename = "="))] @@ -86,7 +86,7 @@ impl AssignmentOperator { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum BinaryOperator { #[cfg_attr(feature = "serialize", serde(rename = "=="))] @@ -272,7 +272,7 @@ impl GetPrecedence for BinaryOperator { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", derive(Tsify))] pub enum LogicalOperator { @@ -304,7 +304,7 @@ impl GetPrecedence for LogicalOperator { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", derive(Tsify))] pub enum UnaryOperator { @@ -350,7 +350,7 @@ impl UnaryOperator { } } -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, layout_inspect::Inspect)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "serialize", derive(Tsify))] pub enum UpdateOperator { diff --git a/crates/oxc_syntax/src/reference.rs b/crates/oxc_syntax/src/reference.rs index 9738e3666d808..3599aa25c20fe 100644 --- a/crates/oxc_syntax/src/reference.rs +++ b/crates/oxc_syntax/src/reference.rs @@ -4,6 +4,7 @@ use oxc_index::define_index_type; use serde::Serialize; define_index_type! { + #[derive(layout_inspect::Inspect)] pub struct ReferenceId = u32; } @@ -76,3 +77,25 @@ impl ReferenceFlag { self.contains(Self::Type) } } + +impl layout_inspect::Inspect for ReferenceFlag { + fn name() -> String { + "ReferenceFlag".to_string() + } + + fn size() -> Option { + Some(std::mem::size_of::()) + } + + fn align() -> Option { + Some(std::mem::align_of::()) + } + + fn def(_collector: &mut layout_inspect::TypesCollector) -> layout_inspect::defs::DefType { + layout_inspect::defs::DefType::Primitive(layout_inspect::defs::DefPrimitive { + name: ::name(), + size: ::size().unwrap(), + align: ::align().unwrap(), + }) + } +} diff --git a/crates/oxc_syntax/src/symbol.rs b/crates/oxc_syntax/src/symbol.rs index 375299db149b9..08e1c3e300e2b 100644 --- a/crates/oxc_syntax/src/symbol.rs +++ b/crates/oxc_syntax/src/symbol.rs @@ -5,6 +5,7 @@ use oxc_index::define_index_type; use serde::Serialize; define_index_type! { + #[derive(layout_inspect::Inspect)] pub struct SymbolId = u32; } diff --git a/crates/oxc_transformer/src/es2015/arrow_functions.rs b/crates/oxc_transformer/src/es2015/arrow_functions.rs index f3eec26d8eb53..ddd09d99d69a5 100644 --- a/crates/oxc_transformer/src/es2015/arrow_functions.rs +++ b/crates/oxc_transformer/src/es2015/arrow_functions.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use oxc_allocator::Vec; -use oxc_ast::ast::*; +use oxc_ast::{ast::*, dummy}; use oxc_span::{Atom, SPAN}; use serde::Deserialize; @@ -124,10 +124,12 @@ impl<'a> ArrowFunctions<'a> { JSXMemberExpressionObject::MemberExpression(expr) => { member_expr = expr; } + JSXMemberExpressionObject::Dummy => dummy!(unreachable), } } } JSXElementName::NamespacedName(_) => {} + JSXElementName::Dummy => dummy!(unreachable), } } diff --git a/crates/oxc_transformer/src/helpers/module_imports.rs b/crates/oxc_transformer/src/helpers/module_imports.rs index 4938533b00656..cacb2fda1ae17 100644 --- a/crates/oxc_transformer/src/helpers/module_imports.rs +++ b/crates/oxc_transformer/src/helpers/module_imports.rs @@ -84,20 +84,21 @@ impl<'a> ModuleImports<'a> { source: &CompactStr, names: std::vec::Vec, ) -> Statement<'a> { - let specifiers = self.ast.new_vec_from_iter(names.into_iter().map(|name| { - ImportDeclarationSpecifier::ImportSpecifier(self.ast.alloc(ImportSpecifier { - span: SPAN, - imported: ModuleExportName::Identifier(IdentifierName::new( - SPAN, - self.ast.new_atom(name.imported.as_str()), - )), - local: BindingIdentifier::new( - SPAN, - self.ast.new_atom(name.local.unwrap_or(name.imported).as_str()), - ), - import_kind: ImportOrExportKind::Value, - })) - })); + let specifiers = + self.ast.new_vec_from_iter(names.into_iter().map(|name| { + ImportDeclarationSpecifier::ImportSpecifier(self.ast.alloc(ImportSpecifier { + span: SPAN, + imported: ModuleExportName::Identifier(self.ast.alloc(IdentifierName::new( + SPAN, + self.ast.new_atom(name.imported.as_str()), + ))), + local: self.ast.alloc(BindingIdentifier::new( + SPAN, + self.ast.new_atom(name.local.unwrap_or(name.imported).as_str()), + )), + import_kind: ImportOrExportKind::Value, + })) + })); let import_stmt = self.ast.import_declaration( SPAN, Some(specifiers), diff --git a/crates/oxc_transformer/src/react/jsx/mod.rs b/crates/oxc_transformer/src/react/jsx/mod.rs index 28d5cd8e12805..593a6673aa5b5 100644 --- a/crates/oxc_transformer/src/react/jsx/mod.rs +++ b/crates/oxc_transformer/src/react/jsx/mod.rs @@ -3,7 +3,7 @@ mod diagnostics; use std::rc::Rc; use oxc_allocator::Vec; -use oxc_ast::{ast::*, AstBuilder}; +use oxc_ast::{ast::*, dummy, AstBuilder}; use oxc_span::{CompactStr, GetSpan, SPAN}; use oxc_syntax::{ identifier::{is_irregular_whitespace, is_line_terminator}, @@ -419,6 +419,7 @@ impl<'a> ReactJsx<'a> { let string_literal = StringLiteral::new(SPAN, name); self.ast().literal_string_expression(string_literal) } + JSXElementName::Dummy => Expression::Dummy, } } @@ -526,6 +527,7 @@ impl<'a> ReactJsx<'a> { JSXMemberExpressionObject::MemberExpression(expr) => { self.transform_jsx_member_expression(expr) } + JSXMemberExpressionObject::Dummy => Expression::Dummy, }; let property = IdentifierName::new(SPAN, expr.property.name.clone()); self.ast().static_member_expression(SPAN, object, property, false) @@ -557,6 +559,7 @@ impl<'a> ReactJsx<'a> { properties.push(object_property); } }, + JSXAttributeItem::Dummy => dummy!(), } } @@ -581,7 +584,9 @@ impl<'a> ReactJsx<'a> { JSXExpression::EmptyExpression(_e) => { self.ast().literal_boolean_expression(BooleanLiteral::new(SPAN, true)) } + JSXExpression::Dummy => Expression::Dummy, }, + Some(JSXAttributeValue::Dummy) => Expression::Dummy, None => self.ast().literal_boolean_expression(BooleanLiteral::new(SPAN, true)), } } @@ -592,6 +597,7 @@ impl<'a> ReactJsx<'a> { JSXChild::ExpressionContainer(e) => match &e.expression { e @ match_expression!(JSXExpression) => Some(self.ast().copy(e.to_expression())), JSXExpression::EmptyExpression(_) => None, + JSXExpression::Dummy => dummy!(), }, JSXChild::Element(e) => Some(self.transform_jsx(&JSXElementOrFragment::Element(e))), JSXChild::Fragment(e) => Some(self.transform_jsx(&JSXElementOrFragment::Fragment(e))), @@ -599,6 +605,7 @@ impl<'a> ReactJsx<'a> { self.ctx.error(SpreadChildrenAreNotSupported(e.span)); None } + JSXChild::Dummy => dummy!(), } } @@ -618,6 +625,7 @@ impl<'a> ReactJsx<'a> { let expr = self.ast().literal_string_expression(StringLiteral::new(SPAN, name)); self.ast().property_key_expression(expr) } + JSXAttributeName::Dummy => PropertyKey::Dummy, } } diff --git a/crates/oxc_transformer/src/react/jsx_source/mod.rs b/crates/oxc_transformer/src/react/jsx_source/mod.rs index 64e838a26f7f0..65c6dcd35c62d 100644 --- a/crates/oxc_transformer/src/react/jsx_source/mod.rs +++ b/crates/oxc_transformer/src/react/jsx_source/mod.rs @@ -80,9 +80,7 @@ impl<'a> ReactJsxSource<'a> { self.should_add_jsx_file_name_variable = true; - let key = JSXAttributeName::Identifier( - self.ctx.ast.alloc(self.ctx.ast.jsx_identifier(SPAN, SOURCE.into())), - ); + let key = JSXAttributeName::Identifier(self.ctx.ast.jsx_identifier(SPAN, SOURCE.into())); let object = self.get_source_object(); let expr = self.ctx.ast.jsx_expression_container(SPAN, JSXExpression::from(object)); let value = JSXAttributeValue::ExpressionContainer(expr); diff --git a/crates/oxc_transformer/src/typescript/annotations.rs b/crates/oxc_transformer/src/typescript/annotations.rs index 8b9742fb1577e..957a55fab3745 100644 --- a/crates/oxc_transformer/src/typescript/annotations.rs +++ b/crates/oxc_transformer/src/typescript/annotations.rs @@ -6,7 +6,7 @@ use crate::context::Ctx; use crate::TypeScriptOptions; use oxc_allocator::Vec; -use oxc_ast::ast::*; +use oxc_ast::{ast::*, dummy}; use oxc_span::{Atom, SPAN}; use oxc_syntax::operator::AssignmentOperator; use rustc_hash::FxHashSet; @@ -66,7 +66,7 @@ impl<'a> TypeScriptAnnotations<'a> { // fix namespace/export-type-only/input.ts // The namespace is type only. So if its name appear in the ExportNamedDeclaration, we should remove it. if let Statement::TSModuleDeclaration(decl) = stmt { - type_names.insert(decl.id.name().clone()); + type_names.insert(decl.id.as_atom()); return false; } @@ -78,7 +78,9 @@ impl<'a> TypeScriptAnnotations<'a> { ModuleDeclaration::ExportNamedDeclaration(decl) => { decl.specifiers.retain(|specifier| { !(specifier.export_kind.is_type() - || type_names.contains(specifier.exported.name())) + || type_names.contains( + specifier.exported.name().unwrap_or_else(|| dummy!(panic)), + )) }); decl.export_kind.is_type() @@ -131,6 +133,7 @@ impl<'a> TypeScriptAnnotations<'a> { references.has_reference(&s.local.name) } + ImportDeclarationSpecifier::Dummy => dummy!(panic), }); } diff --git a/crates/oxc_transformer/src/typescript/collector.rs b/crates/oxc_transformer/src/typescript/collector.rs index 923b15bb3dd08..d95cbd816a69f 100644 --- a/crates/oxc_transformer/src/typescript/collector.rs +++ b/crates/oxc_transformer/src/typescript/collector.rs @@ -29,7 +29,7 @@ impl<'a> TypeScriptReferenceCollector<'a> { for specifier in &decl.specifiers { if specifier.export_kind.is_value() { - self.names.insert(specifier.local.name().clone()); + self.names.insert(specifier.local.as_atom()); } } } diff --git a/crates/oxc_transformer/src/typescript/enum.rs b/crates/oxc_transformer/src/typescript/enum.rs index 789e09dc7c877..14b4f7306b043 100644 --- a/crates/oxc_transformer/src/typescript/enum.rs +++ b/crates/oxc_transformer/src/typescript/enum.rs @@ -1,7 +1,7 @@ use std::rc::Rc; use oxc_allocator::{Box, Vec}; -use oxc_ast::{ast::*, visit::walk_mut, VisitMut}; +use oxc_ast::{ast::*, dummy, visit::walk_mut, VisitMut}; use oxc_span::{Atom, SPAN}; use oxc_syntax::{ number::{NumberBase, ToJsInt32, ToJsString}, @@ -142,6 +142,7 @@ impl<'a> TypeScriptEnum<'a> { TSEnumMemberName::StaticNumericLiteral(_) | match_expression!(TSEnumMemberName) => { unreachable!() } + TSEnumMemberName::Dummy => dummy!(panic), }; let init = if let Some(initializer) = member.initializer.as_ref() { diff --git a/crates/oxc_transformer/src/typescript/module.rs b/crates/oxc_transformer/src/typescript/module.rs index e562def48270e..4aeab475b2c27 100644 --- a/crates/oxc_transformer/src/typescript/module.rs +++ b/crates/oxc_transformer/src/typescript/module.rs @@ -1,5 +1,5 @@ use oxc_allocator::Box; -use oxc_ast::ast::*; +use oxc_ast::{ast::*, dummy}; use oxc_span::SPAN; use super::{ @@ -22,6 +22,7 @@ impl<'a> TypeScript<'a> { qualified_name.right.clone(), false, ), + TSTypeName::Dummy => dummy!(panic), } } @@ -61,6 +62,7 @@ impl<'a> TypeScript<'a> { )); self.ctx.ast.call_expression(SPAN, callee, arguments, false, None) } + TSModuleReference::Dummy => dummy!(panic), }; self.ctx.ast.new_vec_single(self.ctx.ast.variable_declarator( SPAN, diff --git a/crates/oxc_transformer/src/typescript/namespace.rs b/crates/oxc_transformer/src/typescript/namespace.rs index 7cddfae5e858d..e86900412e3c5 100644 --- a/crates/oxc_transformer/src/typescript/namespace.rs +++ b/crates/oxc_transformer/src/typescript/namespace.rs @@ -3,7 +3,7 @@ use rustc_hash::FxHashSet; use super::TypeScript; use oxc_allocator::{Box, Vec}; -use oxc_ast::{ast::*, syntax_directed_operations::BoundNames}; +use oxc_ast::{ast::*, dummy, syntax_directed_operations::BoundNames}; use oxc_span::{Atom, SPAN}; use oxc_syntax::operator::{AssignmentOperator, LogicalOperator}; @@ -33,10 +33,10 @@ impl<'a> TypeScript<'a> { if let Some(transformed_stmt) = self.handle_nested(self.ctx.ast.copy(&decl).unbox(), None) { - let name = decl.id.name(); + let name = decl.id.as_atom(); if names.insert(name.clone()) { new_stmts - .push(Statement::from(self.create_variable_declaration(name))); + .push(Statement::from(self.create_variable_declaration(&name))); } new_stmts.push(transformed_stmt); continue; @@ -53,9 +53,9 @@ impl<'a> TypeScript<'a> { if let Some(transformed_stmt) = self.handle_nested(self.ctx.ast.copy(decl), None) { - let name = decl.id.name(); + let name = decl.id.as_atom(); if names.insert(name.clone()) { - let declaration = self.create_variable_declaration(name); + let declaration = self.create_variable_declaration(&name); let export_named_decl = self .ctx .ast @@ -121,7 +121,7 @@ impl<'a> TypeScript<'a> { parent_export: Option>, ) -> Option> { let mut names: FxHashSet> = FxHashSet::default(); - let real_name = decl.id.name(); + let real_name = decl.id.as_atom(); let name = self.ctx.ast.new_atom(&format!("_{}", real_name.clone())); // path.scope.generateUid(realName.name); @@ -144,6 +144,7 @@ impl<'a> TypeScript<'a> { ); self.ctx.ast.new_vec_single(stmt) } + TSModuleDeclarationBody::Dummy => dummy!(unreachable), } } else { self.ctx.ast.new_vec() @@ -155,7 +156,7 @@ impl<'a> TypeScript<'a> { for stmt in namespace_top_level { match stmt { Statement::TSModuleDeclaration(decl) => { - let module_name = decl.id.name().clone(); + let module_name = decl.id.as_atom(); if let Some(transformed) = self.handle_nested(decl.unbox(), None) { is_empty = false; if names.insert(module_name.clone()) { @@ -218,7 +219,7 @@ impl<'a> TypeScript<'a> { new_stmts.extend(stmts); } Declaration::TSModuleDeclaration(module_decl) => { - let module_name = module_decl.id.name().clone(); + let module_name = module_decl.id.as_atom(); if let Some(transformed) = self.handle_nested( module_decl.unbox(), Some(self.ctx.ast.identifier_reference_expression( @@ -261,7 +262,7 @@ impl<'a> TypeScript<'a> { return None; } - Some(self.transform_namespace(&name, real_name, new_stmts, parent_export)) + Some(self.transform_namespace(&name, &real_name, new_stmts, parent_export)) } // `namespace Foo { }` -> `let Foo; (function (_Foo) { })(Foo || (Foo = {}));` diff --git a/tasks/inspect_ast/Cargo.toml b/tasks/inspect_ast/Cargo.toml new file mode 100644 index 0000000000000..b737d9a9be3ba --- /dev/null +++ b/tasks/inspect_ast/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "oxc_inspect_ast" +version = "0.0.0" +publish = false +authors.workspace = true +description.workspace = true +edition.workspace = true +homepage.workspace = true +keywords.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +oxc_ast = { workspace = true } + +layout_inspect = { workspace = true, features = ["serde", "unique_names"] } +serde_json = { workspace = true } diff --git a/tasks/inspect_ast/lib/index.mjs b/tasks/inspect_ast/lib/index.mjs new file mode 100644 index 0000000000000..7ca3d1c06ae41 --- /dev/null +++ b/tasks/inspect_ast/lib/index.mjs @@ -0,0 +1,149 @@ +import {spawn} from 'child_process'; +import assert from 'assert'; + +function getDefs() { + return new Promise((resolve, reject) => { + const child = spawn('cargo', ['run', '-p', 'oxc_inspect_ast'], { + stdio: ['pipe', 'pipe', 'inherit'] + }); + + let stdout = ''; + child.stdout.on('data', (data) => { + stdout += data.toString(); + }); + + child.on('error', reject); + child.on('close', (code) => { + if (code !== 0) { + reject(new Error(`oxc_inspect_ast exited with code ${code}`)); + } else { + resolve(stdout); + } + }); + }); +} + +async function getTypes() { + const defs = JSON.parse(await getDefs()); + + for (const type of defs) { + type.dependencies = []; + type.dependents = []; + } + + function addDependency(type, dependency) { + if (type.dependencies.includes(dependency)) return; + type.dependencies.push(dependency); + dependency.dependents.push(type); + } + + const types = Object.create(null); + for (const type of defs) { + types[type.name] = type; + delete type.serName; + + const {kind} = type; + if (kind === 'struct') { + type.fields = type.fields.map((field) => { + const childType = defs[field.typeId]; + addDependency(type, childType); + return {name: field.name, type: childType, offset: field.offset}; + }); + delete type.tag; + delete type.transparent; + } else if (kind === 'enum') { + type.variants = type.variants.filter(variant => variant.name !== 'Dummy'); + type.variants = type.variants.map((variant) => { + const childType = variant.valueTypeId === null ? null : defs[variant.valueTypeId]; + if (childType) addDependency(type, childType); + return {name: variant.name, type: childType}; + }); + delete type.tag; + } else if (['vec', 'box', 'option', 'cell'].includes(kind)) { + const childType = defs[type.valueTypeId]; + type.value = childType; + addDependency(type, childType); + delete type.valueTypeId; + } else { + assert(['primitive', 'strSlice'].includes(kind), `Unexpected type kind: ${kind}`); + } + } + return types; +} + +const types = await getTypes(); +// console.dir(types, {depth: 4}); + +console.log('--------------------'); +console.log('> Structs with excess padding:'); +for (const type of Object.values(types)) { + if (type.kind !== 'struct') continue; + + // Calculate size of struct if packed optimally + const fields = type.fields.map(field => ({...field})); + fields.sort((f1, f2) => f1.type.align > f2.type.align ? -1 : 1); + let optimalSize = fields.reduce((size, field) => size + field.type.size, 0); + const mod = optimalSize % type.align; + if (mod !== 0) optimalSize += type.align - mod; + + if (optimalSize < type.size) { + fields.sort((f1, f2) => f1.offset < f2.offset ? -1 : 1); + let last_offset = 0; + const gaps = fields.filter((field) => { + const hasGapBefore = field.offset > last_offset; + last_offset = field.offset + field.type.size; + return hasGapBefore; + }); + console.log(type.name, gaps.map(field => field.name)); + } +} + +console.log('--------------------'); +console.log('> Nested enums:'); +const nestedEnums = Object.values(types).flatMap((type) => { + if (type.kind !== 'enum') return []; + if (type.name === 'FakeForTestingInheritedTypes') return []; + return type.variants.filter(({type: variantType}) => ( + variantType?.kind === 'enum' + || (variantType?.kind === 'box' && variantType.value.kind === 'enum') + )).map(variant => `${type.name} -> ${variant.type.name}`); +}).sort(); +console.log(nestedEnums.join('\n')); + +console.log('--------------------'); +console.log('> Enums with unboxed variants:'); +const enumsWithUnboxedVariants = Object.values(types).flatMap((type) => { + if (type.kind !== 'enum') return []; + return type.variants.filter(({type: variantType}) => variantType && variantType.kind !== 'box') + .map(variant => `${type.name} -> ${variant.type.name}`); +}).sort(); +console.log(enumsWithUnboxedVariants.join('\n')); + +console.log('--------------------'); +console.log('> Structs that need boxing:') +const structsThatNeedBoxing = Object.values(types).filter(type => ( + type.kind === 'struct' + && type.dependents.some( + dep => dep.kind !== 'box' && dep.kind !== 'vec' + && !(dep.kind === 'option' && dep.dependents.every(depDep => depDep.kind === 'vec')) + ) + && ![ + 'Atom', 'Span', 'SourceType', 'ReferenceId', 'SymbolId', 'EmptyObject', 'RegExp', + 'TemplateElementValue', 'Modifiers', 'JSXOpeningFragment', 'JSXClosingFragment' + ].includes(type.name) +)).map(type => type.name).sort(); +console.log(structsThatNeedBoxing.join('\n')); + +// console.log(types.IdentifierName.dependents.map(t => t.name)); + +/* +console.log('--------------------'); +console.log('> Type sizes:'); +Object.values(types).filter(({kind}) => kind === 'struct' || kind === 'enum') + .sort((t1, t2) => { + if (t1.kind < t2.kind) return -1; + if (t1.kind > t2.kind) return 1; + return t1.name < t2.name ? -1 : 1; + }) + .forEach(type => console.log(`${type.name}: ${type.size}`)); +*/ diff --git a/tasks/inspect_ast/package.json b/tasks/inspect_ast/package.json new file mode 100644 index 0000000000000..1890e57434f33 --- /dev/null +++ b/tasks/inspect_ast/package.json @@ -0,0 +1,6 @@ +{ + "name": "inspect_ast", + "version": "0.0.0", + "main": "lib/index.mjs", + "packageManager": "pnpm@9.0.5" +} diff --git a/tasks/inspect_ast/pnpm-lock.yaml b/tasks/inspect_ast/pnpm-lock.yaml new file mode 100644 index 0000000000000..9b60ae1782d6d --- /dev/null +++ b/tasks/inspect_ast/pnpm-lock.yaml @@ -0,0 +1,9 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: {} diff --git a/tasks/inspect_ast/src/main.rs b/tasks/inspect_ast/src/main.rs new file mode 100644 index 0000000000000..587f397fd7b4b --- /dev/null +++ b/tasks/inspect_ast/src/main.rs @@ -0,0 +1,11 @@ +#![allow(dead_code)] + +use layout_inspect::inspect; + +use oxc_ast::ast::FakeForTestingInheritedTypes; + +pub fn main() { + let types = inspect::(); + let json = serde_json::to_string_pretty(&types).unwrap(); + println!("{json}"); +} diff --git a/tasks/rulegen/src/main.rs b/tasks/rulegen/src/main.rs index 4c841d9c213a5..37a31f0c6c75b 100644 --- a/tasks/rulegen/src/main.rs +++ b/tasks/rulegen/src/main.rs @@ -13,7 +13,7 @@ use oxc_ast::{ PropertyKey, Statement, StaticMemberExpression, StringLiteral, TaggedTemplateExpression, TemplateLiteral, }, - Visit, + dummy, Visit, }; use oxc_parser::Parser; use oxc_span::{GetSpan, SourceType, Span}; @@ -222,6 +222,7 @@ impl<'a> Visit<'a> for TestCase<'a> { _ => continue, }, ObjectPropertyKind::SpreadProperty(_) => continue, + ObjectPropertyKind::Dummy => dummy!(), } } }