diff --git a/Cargo.lock b/Cargo.lock index f98e867f310f8..0990f484e8028 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1769,6 +1769,7 @@ dependencies = [ "bitflags 2.6.0", "dashmap 6.0.1", "nonmax", + "oxc_allocator", "oxc_ast_macros", "oxc_index", "oxc_span", diff --git a/crates/oxc_ast_macros/src/lib.rs b/crates/oxc_ast_macros/src/lib.rs index c6726f109fbd1..7701e27244d8c 100644 --- a/crates/oxc_ast_macros/src/lib.rs +++ b/crates/oxc_ast_macros/src/lib.rs @@ -53,3 +53,32 @@ pub fn ast(_args: TokenStream, input: TokenStream) -> TokenStream { pub fn ast_derive(_item: TokenStream) -> TokenStream { TokenStream::new() } + +/// Derive macro generating an impl of the trait `CloneIn`. +/// +/// NOTE: This is an internal macro! +/// # Panics +/// +#[proc_macro_derive(CloneIn)] +pub fn derive_clone_in(item: TokenStream) -> TokenStream { + let item = syn::parse_macro_input!(item as syn::Item); + match &item { + syn::Item::Struct(syn::ItemStruct { ident, generics, .. }) + | syn::Item::Enum(syn::ItemEnum { ident, generics, .. }) + if generics.params.is_empty() => + { + quote! { + #[automatically_derived] + impl<'alloc> ::oxc_allocator::CloneIn<'alloc> for #ident { + type Cloned = #ident; + + fn clone_in(&self, _: &'alloc ::oxc_allocator::Allocator) -> Self::Cloned { + std::clone::Clone::clone(self) + } + } + } + .into() + } + _ => panic!("At the moment `CloneIn` derive macro only works for types without lifetimes and/or generic params"), + } +} diff --git a/crates/oxc_syntax/Cargo.toml b/crates/oxc_syntax/Cargo.toml index 0bd42f63bb346..2d6b76c1a739d 100644 --- a/crates/oxc_syntax/Cargo.toml +++ b/crates/oxc_syntax/Cargo.toml @@ -23,6 +23,7 @@ doctest = false oxc_index = { workspace = true } oxc_span = { workspace = true } oxc_ast_macros = { workspace = true } +oxc_allocator = { workspace = true } unicode-id-start = { workspace = true } bitflags = { workspace = true } @@ -40,3 +41,9 @@ wasm-bindgen = { workspace = true, optional = true } default = [] to_js_string = ["dep:ryu-js"] serialize = ["bitflags/serde", "dep:serde", "dep:tsify", "dep:wasm-bindgen", "oxc_index/serialize"] + +[package.metadata.cargo-shear] +# We use `oxc_ast_macros::CloneIn` which expands to use `oxc_allocator`. +# To fix this we have to expose `CloneIn` through `oxc_allocator` +# (and probably move it to `oxc_allocator_derive`). +ignored = ["oxc_allocator"] diff --git a/crates/oxc_syntax/src/number.rs b/crates/oxc_syntax/src/number.rs index 36c76c409cf2d..d13638316743c 100644 --- a/crates/oxc_syntax/src/number.rs +++ b/crates/oxc_syntax/src/number.rs @@ -1,7 +1,7 @@ -use oxc_ast_macros::ast; +use oxc_ast_macros::{ast, CloneIn}; #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CloneIn)] pub enum NumberBase { Float = 0, Decimal = 1, @@ -17,7 +17,7 @@ impl NumberBase { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CloneIn)] pub enum BigintBase { Decimal = 0, Binary = 1, diff --git a/crates/oxc_syntax/src/operator.rs b/crates/oxc_syntax/src/operator.rs index be715d29f3c56..14ddc11e153d6 100644 --- a/crates/oxc_syntax/src/operator.rs +++ b/crates/oxc_syntax/src/operator.rs @@ -4,12 +4,12 @@ #[cfg(feature = "serialize")] use ::{serde::Serialize, tsify::Tsify}; -use oxc_ast_macros::ast; +use oxc_ast_macros::{ast, CloneIn}; use crate::precedence::{GetPrecedence, Precedence}; #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CloneIn)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum AssignmentOperator { #[serde(rename = "=")] @@ -88,7 +88,7 @@ impl AssignmentOperator { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CloneIn)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum BinaryOperator { #[serde(rename = "==")] @@ -276,7 +276,7 @@ impl GetPrecedence for BinaryOperator { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CloneIn)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum LogicalOperator { #[serde(rename = "||")] @@ -316,7 +316,7 @@ impl GetPrecedence for LogicalOperator { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CloneIn)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum UnaryOperator { #[serde(rename = "-")] @@ -369,7 +369,7 @@ impl UnaryOperator { } #[ast] -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CloneIn)] #[cfg_attr(feature = "serialize", derive(Serialize, Tsify))] pub enum UpdateOperator { #[serde(rename = "++")] diff --git a/crates/oxc_syntax/src/reference.rs b/crates/oxc_syntax/src/reference.rs index b90dbfbe786f9..4b8f5f55cb0d2 100644 --- a/crates/oxc_syntax/src/reference.rs +++ b/crates/oxc_syntax/src/reference.rs @@ -1,5 +1,6 @@ use bitflags::bitflags; use nonmax::NonMaxU32; +use oxc_ast_macros::CloneIn; #[cfg(feature = "serialize")] use serde::{Serialize, Serializer}; @@ -45,7 +46,7 @@ export type ReferenceFlag = { "#; bitflags! { - #[derive(Debug, Default, Clone, Copy, Eq, PartialEq)] + #[derive(Debug, Default, Clone, Copy, Eq, PartialEq, CloneIn)] #[cfg_attr(feature = "serialize", derive(Serialize))] pub struct ReferenceFlag: u8 { const None = 0;