swc_ecma_compat_es3/
member_expr_lits.rs1use 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
6pub 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 || !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}