oxc_allocator/
take_in.rs

1use std::{cell::Cell, mem, num};
2
3use crate::{Allocator, AllocatorAccessor, Box, Vec};
4
5/// A trait to replace an existing AST node with a dummy.
6pub trait TakeIn<'a>: Dummy<'a> {
7    /// Replace node with a dummy.
8    #[must_use]
9    fn take_in<A: AllocatorAccessor<'a>>(&mut self, allocator_accessor: A) -> Self {
10        let allocator = allocator_accessor.allocator();
11        let dummy = Dummy::dummy(allocator);
12        mem::replace(self, dummy)
13    }
14
15    /// Replace node with a boxed dummy.
16    #[must_use]
17    fn take_in_box<A: AllocatorAccessor<'a>>(&mut self, allocator_accessor: A) -> Box<'a, Self> {
18        let allocator = allocator_accessor.allocator();
19        let dummy = Dummy::dummy(allocator);
20        Box::new_in(mem::replace(self, dummy), allocator)
21    }
22}
23
24impl<'a, T> TakeIn<'a> for Vec<'a, T> {}
25
26/// A trait to create a dummy AST node.
27pub trait Dummy<'a>: Sized {
28    /// Create a dummy node.
29    fn dummy(allocator: &'a Allocator) -> Self;
30}
31
32impl<'a, T> Dummy<'a> for Option<T> {
33    /// Create a dummy [`Option`].
34    #[expect(clippy::inline_always)]
35    #[inline(always)]
36    fn dummy(_allocator: &'a Allocator) -> Self {
37        None
38    }
39}
40
41impl<'a, T: Dummy<'a>> Dummy<'a> for Box<'a, T> {
42    /// Create a dummy [`Box`].
43    #[inline]
44    fn dummy(allocator: &'a Allocator) -> Self {
45        Box::new_in(Dummy::dummy(allocator), allocator)
46    }
47}
48
49impl<'a, T> Dummy<'a> for Vec<'a, T> {
50    /// Create a dummy [`Vec`].
51    #[inline]
52    fn dummy(allocator: &'a Allocator) -> Self {
53        Vec::new_in(allocator)
54    }
55}
56
57impl<'a, T: Dummy<'a>> Dummy<'a> for Cell<T> {
58    /// Create a dummy [`Cell`].
59    #[expect(clippy::inline_always)]
60    #[inline(always)]
61    fn dummy(allocator: &'a Allocator) -> Self {
62        Cell::new(Dummy::dummy(allocator))
63    }
64}
65
66impl<'a> Dummy<'a> for () {
67    #[inline(always)]
68    fn dummy(_allocator: &'a Allocator) {}
69}
70
71impl<'a> Dummy<'a> for bool {
72    #[expect(clippy::inline_always)]
73    #[inline(always)]
74    fn dummy(_allocator: &'a Allocator) -> Self {
75        false
76    }
77}
78
79impl<'a> Dummy<'a> for &'a str {
80    #[expect(clippy::inline_always)]
81    #[inline(always)]
82    fn dummy(_allocator: &'a Allocator) -> Self {
83        ""
84    }
85}
86
87macro_rules! dummy_impl_int {
88    ($ty:ident) => {
89        impl<'a> Dummy<'a> for $ty {
90            #[inline(always)]
91            fn dummy(_allocator: &'a Allocator) -> Self {
92                0
93            }
94        }
95    };
96}
97
98dummy_impl_int!(u8);
99dummy_impl_int!(u16);
100dummy_impl_int!(u32);
101dummy_impl_int!(u64);
102dummy_impl_int!(u128);
103dummy_impl_int!(usize);
104dummy_impl_int!(i8);
105dummy_impl_int!(i16);
106dummy_impl_int!(i32);
107dummy_impl_int!(i64);
108dummy_impl_int!(i128);
109dummy_impl_int!(isize);
110
111macro_rules! dummy_impl_float {
112    ($ty:ident) => {
113        impl<'a> Dummy<'a> for $ty {
114            #[inline(always)]
115            fn dummy(_allocator: &'a Allocator) -> Self {
116                0.0
117            }
118        }
119    };
120}
121
122dummy_impl_float!(f32);
123dummy_impl_float!(f64);
124
125macro_rules! dummy_impl_non_zero {
126    ($ty:ident) => {
127        impl<'a> Dummy<'a> for num::$ty {
128            #[inline(always)]
129            fn dummy(_allocator: &'a Allocator) -> Self {
130                Self::MIN
131            }
132        }
133    };
134}
135
136dummy_impl_non_zero!(NonZeroU8);
137dummy_impl_non_zero!(NonZeroU16);
138dummy_impl_non_zero!(NonZeroU32);
139dummy_impl_non_zero!(NonZeroU64);
140dummy_impl_non_zero!(NonZeroU128);
141dummy_impl_non_zero!(NonZeroUsize);
142dummy_impl_non_zero!(NonZeroI8);
143dummy_impl_non_zero!(NonZeroI16);
144dummy_impl_non_zero!(NonZeroI32);
145dummy_impl_non_zero!(NonZeroI64);
146dummy_impl_non_zero!(NonZeroI128);
147dummy_impl_non_zero!(NonZeroIsize);