swc_ecma_transforms_module/
top_level_this.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use swc_ecma_ast::*;
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};

pub struct TopLevelThis {
    found: bool,
    this: Expr,
}

pub(crate) fn top_level_this<V>(node: &mut V, replace_with: Expr) -> bool
where
    V: VisitMutWith<TopLevelThis>,
{
    let mut v = TopLevelThis {
        this: replace_with,
        found: false,
    };
    node.visit_mut_with(&mut v);
    v.found
}

impl VisitMut for TopLevelThis {
    noop_visit_mut_type!(fail);

    noop_visit_mut_type!(visit_mut_function, Function);

    fn visit_mut_class_member(&mut self, n: &mut ClassMember) {
        match n {
            ClassMember::Method(ClassMethod {
                key: PropName::Computed(computed),
                ..
            })
            | ClassMember::ClassProp(ClassProp {
                key: PropName::Computed(computed),
                ..
            }) => {
                computed.visit_mut_with(self);
            }
            _ => {}
        }
    }

    fn visit_mut_prop(&mut self, n: &mut Prop) {
        match n {
            Prop::KeyValue(..) => {
                n.visit_mut_children_with(self);
            }
            Prop::Getter(GetterProp {
                key: PropName::Computed(computed),
                ..
            })
            | Prop::Setter(SetterProp {
                key: PropName::Computed(computed),
                ..
            })
            | Prop::Method(MethodProp {
                key: PropName::Computed(computed),
                ..
            }) => computed.visit_mut_children_with(self),
            _ => {}
        }
    }

    fn visit_mut_expr(&mut self, n: &mut Expr) {
        if let Expr::This(ThisExpr { span }) = n {
            self.found = true;

            let mut this = self.this.clone();
            match &mut this {
                // for void 0
                Expr::Unary(unary_expr) => unary_expr.span = *span,
                Expr::Ident(ident) => ident.span = *span,
                Expr::Member(member) => member.span = *span,

                _ => {
                    unimplemented!();
                }
            }

            *n = this;
        } else {
            n.visit_mut_children_with(self);
        }
    }
}