swc_ecma_utils/
node_ignore_span.rs

1use std::{borrow::Cow, fmt::Debug, hash::Hash};
2
3use swc_common::EqIgnoreSpan;
4use swc_ecma_ast::{Expr, MemberProp};
5
6/// A newtype that will ignore Span while doing `eq` or `hash`.
7pub struct NodeIgnoringSpan<'a, Node: ToOwned + Debug>(Cow<'a, Node>);
8
9impl<Node: ToOwned + Debug> Debug for NodeIgnoringSpan<'_, Node> {
10    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
11        f.debug_tuple("NodeIgnoringSpan").field(&*self.0).finish()
12    }
13}
14
15impl<'a, Node: ToOwned + Debug> NodeIgnoringSpan<'a, Node> {
16    #[inline]
17    pub fn borrowed(expr: &'a Node) -> Self {
18        Self(Cow::Borrowed(expr))
19    }
20
21    #[inline]
22    pub fn owned(expr: <Node as ToOwned>::Owned) -> Self {
23        Self(Cow::Owned(expr))
24    }
25}
26
27impl<Node: EqIgnoreSpan + ToOwned + Debug> PartialEq for NodeIgnoringSpan<'_, Node> {
28    fn eq(&self, other: &Self) -> bool {
29        self.0.eq_ignore_span(&other.0)
30    }
31}
32
33impl<Node: EqIgnoreSpan + ToOwned + Debug> Eq for NodeIgnoringSpan<'_, Node> {}
34
35// TODO: This is only a workaround for Expr. we need something like
36// `hash_ignore_span` for each node in the end.
37impl Hash for NodeIgnoringSpan<'_, Expr> {
38    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
39        // In pratice, most of cases/input we are dealing with are Expr::Member or
40        // Expr::Ident.
41        match &*self.0 {
42            Expr::Ident(i) => {
43                i.sym.hash(state);
44            }
45            Expr::Member(i) => {
46                {
47                    NodeIgnoringSpan::borrowed(i.obj.as_ref()).hash(state);
48                }
49                if let MemberProp::Ident(prop) = &i.prop {
50                    prop.sym.hash(state);
51                }
52            }
53            _ => {
54                // Other expression kinds would fallback to the same empty hash.
55                // So, they will spend linear time to do comparisons.
56            }
57        }
58    }
59}