1use std::{cell::RefCell, rc::Rc, sync::Arc};
2
3use num_bigint::BigInt;
4
5use crate::{BytePos, Span};
6
7pub trait EqIgnoreSpan {
9 fn eq_ignore_span(&self, other: &Self) -> bool;
10}
11
12impl EqIgnoreSpan for Span {
13 #[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
73pub trait TypeEq {
90 fn type_eq(&self, other: &Self) -> bool;
92}
93
94impl TypeEq for Span {
95 #[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
124macro_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
197impl<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);