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