swc_ecma_compat_es3/
member_expr_lits.rs

1use swc_ecma_ast::*;
2use swc_ecma_utils::is_valid_ident;
3use swc_ecma_visit::{fold_pass, standard_only_fold, Fold, FoldWith};
4use swc_trace_macro::swc_trace;
5
6/// babel: `transform-member-expression-literals`
7///
8/// # Input
9/// ```js
10/// obj["foo"] = "isValid";
11///
12/// obj.const = "isKeyword";
13/// obj["var"] = "isKeyword";
14/// ```
15///
16/// # Output
17/// ```js
18/// obj.foo = "isValid";
19///
20/// obj["const"] = "isKeyword";
21/// obj["var"] = "isKeyword";
22/// ```
23pub fn member_expression_literals() -> impl Pass {
24    fold_pass(MemberExprLit)
25}
26#[derive(Default, Clone, Copy)]
27struct MemberExprLit;
28
29#[swc_trace]
30impl Fold for MemberExprLit {
31    standard_only_fold!();
32
33    fn fold_member_expr(&mut self, e: MemberExpr) -> MemberExpr {
34        let e: MemberExpr = e.fold_children_with(self);
35
36        if let MemberProp::Ident(i) = e.prop {
37            if i.sym.is_reserved() || i.sym.is_reserved_in_strict_mode(true)
38                        || i.sym.is_reserved_in_es3()
39                        // it's not bind, so you could use eval
40                        || !is_valid_ident(&i.sym)
41            {
42                return MemberExpr {
43                    prop: MemberProp::Computed(ComputedPropName {
44                        span: i.span,
45                        expr: Lit::Str(Str {
46                            span: i.span,
47                            raw: None,
48                            value: i.sym,
49                        })
50                        .into(),
51                    }),
52                    ..e
53                };
54            } else {
55                return MemberExpr {
56                    prop: MemberProp::Ident(IdentName::new(i.sym, i.span)),
57                    ..e
58                };
59            }
60        };
61
62        e
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use swc_ecma_transforms_testing::test;
69
70    use super::*;
71
72    test!(
73        ::swc_ecma_parser::Syntax::default(),
74        |_| fold_pass(MemberExprLit),
75        basic,
76        r#"obj["foo"] = "isValid";
77
78obj.const = "isKeyword";
79obj["var"] = "isKeyword";"#,
80        ok_if_code_eq
81    );
82
83    test!(
84        ::swc_ecma_parser::Syntax::default(),
85        |_| fold_pass(MemberExprLit),
86        issue_206,
87        "const number = foo[bar1][baz1]"
88    );
89
90    test!(
91        ::swc_ecma_parser::Syntax::default(),
92        |_| fold_pass(MemberExprLit),
93        issue_211,
94        "_query[idx]=$this.attr('data-ref');"
95    );
96}