swc_common/
eq.rs

1use std::{cell::RefCell, rc::Rc, sync::Arc};
2
3use num_bigint::BigInt;
4
5use crate::{BytePos, Span};
6
7/// Derive with `#[derive(EqIgnoreSpan)]`.
8pub trait EqIgnoreSpan {
9    fn eq_ignore_span(&self, other: &Self) -> bool;
10}
11
12impl EqIgnoreSpan for Span {
13    /// Always returns true
14    #[inline]
15    fn eq_ignore_span(&self, _: &Self) -> bool {
16        true
17    }
18}
19
20impl EqIgnoreSpan for swc_atoms::Atom {
21    #[inline]
22    fn eq_ignore_span(&self, r: &Self) -> bool {
23        self == r
24    }
25}
26
27impl EqIgnoreSpan for swc_atoms::Wtf8Atom {
28    #[inline]
29    fn eq_ignore_span(&self, r: &Self) -> bool {
30        self == r
31    }
32}
33
34impl<T> EqIgnoreSpan for [T]
35where
36    T: EqIgnoreSpan,
37{
38    fn eq_ignore_span(&self, other: &Self) -> bool {
39        self.len() == other.len()
40            && self
41                .iter()
42                .zip(other.iter())
43                .all(|(a, b)| a.eq_ignore_span(b))
44    }
45}
46
47impl<T> EqIgnoreSpan for Option<T>
48where
49    T: EqIgnoreSpan,
50{
51    fn eq_ignore_span(&self, other: &Self) -> bool {
52        match (self, other) {
53            (Some(l), Some(r)) => l.eq_ignore_span(r),
54            (None, None) => true,
55            _ => false,
56        }
57    }
58}
59
60impl<T> EqIgnoreSpan for Vec<T>
61where
62    T: EqIgnoreSpan,
63{
64    fn eq_ignore_span(&self, other: &Self) -> bool {
65        self.len() == other.len()
66            && self
67                .iter()
68                .zip(other.iter())
69                .all(|(a, b)| a.eq_ignore_span(b))
70    }
71}
72
73// nightly_only!(
74//     impl<T> EqIgnoreSpan for swc_allocator::vec::Vec<T>
75//     where
76//         T: EqIgnoreSpan,
77//     {
78//         fn eq_ignore_span(&self, other: &Self) -> bool {
79//             self.len() == other.len()
80//                 && self
81//                     .iter()
82//                     .zip(other.iter())
83//                     .all(|(a, b)| a.eq_ignore_span(b))
84//         }
85//     }
86// );
87
88/// Derive with `#[derive(TypeEq)]`.
89pub trait TypeEq {
90    /// **Note**: This method should return `true` for non-type values.
91    fn type_eq(&self, other: &Self) -> bool;
92}
93
94impl TypeEq for Span {
95    /// Always returns true
96    #[inline]
97    fn type_eq(&self, _: &Self) -> bool {
98        true
99    }
100}
101
102impl<T> TypeEq for Option<T>
103where
104    T: TypeEq,
105{
106    fn type_eq(&self, other: &Self) -> bool {
107        match (self, other) {
108            (Some(l), Some(r)) => l.type_eq(r),
109            (None, None) => true,
110            _ => false,
111        }
112    }
113}
114
115impl<T> TypeEq for Vec<T>
116where
117    T: TypeEq,
118{
119    fn type_eq(&self, other: &Self) -> bool {
120        self.len() == other.len() && self.iter().zip(other.iter()).all(|(a, b)| a.type_eq(b))
121    }
122}
123
124/// Implement traits using PartialEq
125macro_rules! eq {
126    ($T:ty) => {
127        impl EqIgnoreSpan for $T {
128            #[inline]
129            fn eq_ignore_span(&self, other: &Self) -> bool {
130                self == other
131            }
132        }
133
134        impl TypeEq for $T {
135            #[inline]
136            fn type_eq(&self, other: &Self) -> bool {
137                self == other
138            }
139        }
140    };
141
142    (
143        $(
144            $T:ty
145        ),*
146    ) => {
147        $(
148            eq!($T);
149        )*
150    };
151}
152
153eq!(BytePos);
154eq!(bool);
155eq!(usize, u8, u16, u32, u64, u128);
156eq!(isize, i8, i16, i32, i64, i128);
157eq!(f32, f64);
158eq!(char, str, String);
159
160macro_rules! deref {
161    ($T:ident) => {
162        impl<N> EqIgnoreSpan for $T<N>
163        where
164            N: EqIgnoreSpan,
165        {
166            #[inline]
167            fn eq_ignore_span(&self, other: &Self) -> bool {
168                (**self).eq_ignore_span(&**other)
169            }
170        }
171
172        impl<N> TypeEq for $T<N>
173        where
174            N: TypeEq,
175        {
176            #[inline]
177            fn type_eq(&self, other: &Self) -> bool {
178                (**self).type_eq(&**other)
179            }
180        }
181    };
182
183
184    (
185        $(
186            $T:ident
187        ),*
188    ) => {
189        $(
190            deref!($T);
191        )*
192    };
193}
194
195deref!(Box, Rc, Arc);
196
197// swc_allocator::nightly_only!(
198//     impl<N> EqIgnoreSpan for swc_allocator::boxed::Box<N>
199//     where
200//         N: EqIgnoreSpan,
201//     {
202//         #[inline]
203//         fn eq_ignore_span(&self, other: &Self) -> bool {
204//             (**self).eq_ignore_span(&**other)
205//         }
206//     }
207
208//     impl<N> TypeEq for swc_allocator::boxed::Box<N>
209//     where
210//         N: TypeEq,
211//     {
212//         #[inline]
213//         fn type_eq(&self, other: &Self) -> bool {
214//             (**self).type_eq(&**other)
215//         }
216//     }
217// );
218
219impl<N> EqIgnoreSpan for &N
220where
221    N: EqIgnoreSpan,
222{
223    #[inline]
224    fn eq_ignore_span(&self, other: &Self) -> bool {
225        (**self).eq_ignore_span(&**other)
226    }
227}
228
229impl<N> TypeEq for &N
230where
231    N: TypeEq,
232{
233    #[inline]
234    fn type_eq(&self, other: &Self) -> bool {
235        (**self).type_eq(&**other)
236    }
237}
238
239impl<N> EqIgnoreSpan for RefCell<N>
240where
241    N: EqIgnoreSpan,
242{
243    fn eq_ignore_span(&self, other: &Self) -> bool {
244        self.borrow().eq_ignore_span(&*other.borrow())
245    }
246}
247
248impl<N> TypeEq for RefCell<N>
249where
250    N: TypeEq,
251{
252    fn type_eq(&self, other: &Self) -> bool {
253        self.borrow().type_eq(&*other.borrow())
254    }
255}
256
257impl EqIgnoreSpan for BigInt {
258    fn eq_ignore_span(&self, other: &Self) -> bool {
259        self == other
260    }
261}
262impl TypeEq for BigInt {
263    fn type_eq(&self, other: &Self) -> bool {
264        self == other
265    }
266}
267
268macro_rules! tuple {
269    (
270        $num:tt: $F:ident
271    ) => {};
272
273
274    (
275        $first:tt: $F:ident,
276        $(
277            $num:tt: $N:ident
278        ),*
279    ) =>{
280        tuple!($($num: $N),*);
281
282        impl<$F: EqIgnoreSpan, $($N: EqIgnoreSpan),*> EqIgnoreSpan for ($F, $($N,)*) {
283            fn eq_ignore_span(&self,rhs: &Self) -> bool {
284                self.$first.eq_ignore_span(&rhs.$first) &&
285                $(
286                    self.$num.eq_ignore_span(&rhs.$num)
287                )
288                && *
289            }
290        }
291
292        impl<$F: TypeEq, $($N: TypeEq),*> TypeEq for ($F, $($N,)*) {
293            fn type_eq(&self,rhs: &Self) -> bool {
294                self.$first.type_eq(&rhs.$first) &&
295                $(
296                    self.$num.type_eq(&rhs.$num)
297                )
298                && *
299            }
300        }
301    };
302}
303
304tuple!(
305    25: Z,
306    24: Y,
307    23: X,
308    22: W,
309    21: V,
310    20: U,
311    19: T,
312    18: S,
313    17: R,
314    16: Q,
315    15: P,
316    14: O,
317    13: N,
318    12: M,
319    11: L,
320    10: K,
321    9: J,
322    8: I,
323    7: H,
324    6: G,
325    5: F,
326    4: E,
327    3: D,
328    2: C,
329    1: B,
330    0: A
331);