swc_ecma_transforms_module/
top_level_this.rs

1use swc_ecma_ast::*;
2use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
3
4pub struct TopLevelThis {
5    found: bool,
6    this: Expr,
7}
8
9pub(crate) fn top_level_this<V>(node: &mut V, replace_with: Expr) -> bool
10where
11    V: VisitMutWith<TopLevelThis>,
12{
13    let mut v = TopLevelThis {
14        this: replace_with,
15        found: false,
16    };
17    node.visit_mut_with(&mut v);
18    v.found
19}
20
21impl VisitMut for TopLevelThis {
22    noop_visit_mut_type!(fail);
23
24    noop_visit_mut_type!(visit_mut_function, Function);
25
26    fn visit_mut_class_member(&mut self, n: &mut ClassMember) {
27        match n {
28            ClassMember::Method(ClassMethod {
29                key: PropName::Computed(computed),
30                ..
31            })
32            | ClassMember::ClassProp(ClassProp {
33                key: PropName::Computed(computed),
34                ..
35            }) => {
36                computed.visit_mut_with(self);
37            }
38            _ => {}
39        }
40    }
41
42    fn visit_mut_prop(&mut self, n: &mut Prop) {
43        match n {
44            Prop::KeyValue(..) => {
45                n.visit_mut_children_with(self);
46            }
47            Prop::Getter(GetterProp {
48                key: PropName::Computed(computed),
49                ..
50            })
51            | Prop::Setter(SetterProp {
52                key: PropName::Computed(computed),
53                ..
54            })
55            | Prop::Method(MethodProp {
56                key: PropName::Computed(computed),
57                ..
58            }) => computed.visit_mut_children_with(self),
59            _ => {}
60        }
61    }
62
63    fn visit_mut_expr(&mut self, n: &mut Expr) {
64        if let Expr::This(ThisExpr { span }) = n {
65            self.found = true;
66
67            let mut this = self.this.clone();
68            match &mut this {
69                // for void 0
70                Expr::Unary(unary_expr) => unary_expr.span = *span,
71                Expr::Ident(ident) => ident.span = *span,
72                Expr::Member(member) => member.span = *span,
73
74                _ => {
75                    unimplemented!();
76                }
77            }
78
79            *n = this;
80        } else {
81            n.visit_mut_children_with(self);
82        }
83    }
84}