Skip to main content

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
26impl<'a, T> TakeIn<'a> for Box<'a, [T]> {}
27
28/// A trait to create a dummy AST node.
29pub trait Dummy<'a>: Sized {
30    /// Create a dummy node.
31    fn dummy(allocator: &'a Allocator) -> Self;
32}
33
34impl<'a, T> Dummy<'a> for Option<T> {
35    /// Create a dummy [`Option`].
36    #[expect(clippy::inline_always)]
37    #[inline(always)]
38    fn dummy(_allocator: &'a Allocator) -> Self {
39        None
40    }
41}
42
43impl<'a, T: Dummy<'a>> Dummy<'a> for Box<'a, T> {
44    /// Create a dummy [`Box`].
45    #[inline]
46    fn dummy(allocator: &'a Allocator) -> Self {
47        Box::new_in(Dummy::dummy(allocator), allocator)
48    }
49}
50
51impl<'a, T> Dummy<'a> for Box<'a, [T]> {
52    /// Create a dummy empty [`Box<[T]>`] boxed slice.
53    #[inline]
54    fn dummy(_allocator: &'a Allocator) -> Self {
55        Box::new_empty_boxed_slice()
56    }
57}
58
59impl<'a, T> Dummy<'a> for Vec<'a, T> {
60    /// Create a dummy [`Vec`].
61    #[inline]
62    fn dummy(allocator: &'a Allocator) -> Self {
63        Vec::new_in(allocator)
64    }
65}
66
67impl<'a, T: Dummy<'a>> Dummy<'a> for Cell<T> {
68    /// Create a dummy [`Cell`].
69    #[expect(clippy::inline_always)]
70    #[inline(always)]
71    fn dummy(allocator: &'a Allocator) -> Self {
72        Cell::new(Dummy::dummy(allocator))
73    }
74}
75
76impl<'a> Dummy<'a> for () {
77    #[inline(always)]
78    fn dummy(_allocator: &'a Allocator) {}
79}
80
81impl<'a> Dummy<'a> for bool {
82    #[expect(clippy::inline_always)]
83    #[inline(always)]
84    fn dummy(_allocator: &'a Allocator) -> Self {
85        false
86    }
87}
88
89impl<'a> Dummy<'a> for &'a str {
90    #[expect(clippy::inline_always)]
91    #[inline(always)]
92    fn dummy(_allocator: &'a Allocator) -> Self {
93        ""
94    }
95}
96
97macro_rules! dummy_impl_int {
98    ($ty:ident) => {
99        impl<'a> Dummy<'a> for $ty {
100            #[inline(always)]
101            fn dummy(_allocator: &'a Allocator) -> Self {
102                0
103            }
104        }
105    };
106}
107
108dummy_impl_int!(u8);
109dummy_impl_int!(u16);
110dummy_impl_int!(u32);
111dummy_impl_int!(u64);
112dummy_impl_int!(u128);
113dummy_impl_int!(usize);
114dummy_impl_int!(i8);
115dummy_impl_int!(i16);
116dummy_impl_int!(i32);
117dummy_impl_int!(i64);
118dummy_impl_int!(i128);
119dummy_impl_int!(isize);
120
121macro_rules! dummy_impl_float {
122    ($ty:ident) => {
123        impl<'a> Dummy<'a> for $ty {
124            #[inline(always)]
125            fn dummy(_allocator: &'a Allocator) -> Self {
126                0.0
127            }
128        }
129    };
130}
131
132dummy_impl_float!(f32);
133dummy_impl_float!(f64);
134
135macro_rules! dummy_impl_non_zero {
136    ($ty:ident) => {
137        impl<'a> Dummy<'a> for num::$ty {
138            #[inline(always)]
139            fn dummy(_allocator: &'a Allocator) -> Self {
140                Self::MIN
141            }
142        }
143    };
144}
145
146dummy_impl_non_zero!(NonZeroU8);
147dummy_impl_non_zero!(NonZeroU16);
148dummy_impl_non_zero!(NonZeroU32);
149dummy_impl_non_zero!(NonZeroU64);
150dummy_impl_non_zero!(NonZeroU128);
151dummy_impl_non_zero!(NonZeroUsize);
152dummy_impl_non_zero!(NonZeroI8);
153dummy_impl_non_zero!(NonZeroI16);
154dummy_impl_non_zero!(NonZeroI32);
155dummy_impl_non_zero!(NonZeroI64);
156dummy_impl_non_zero!(NonZeroI128);
157dummy_impl_non_zero!(NonZeroIsize);