swc_ecma_compat_es3/
prop_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-property-literals`
7///
8/// # Input
9/// ```js
10/// var foo = {
11///   // changed
12///   "bar": function () {},
13///   "1": function () {},
14///
15///   // not changed
16///   "default": 1,
17///   [a]: 2,
18///   foo: 1
19/// };
20/// ```
21///
22/// # Output
23/// ```js
24/// var foo = {
25///   bar: function () {},
26///   1: function () {},
27///
28///   "default": 1,
29///   [a]: 2,
30///   foo: 1
31/// };
32/// ```
33pub fn property_literals() -> impl Pass {
34    fold_pass(PropertyLiteral)
35}
36
37struct PropertyLiteral;
38
39#[swc_trace]
40impl Fold for PropertyLiteral {
41    standard_only_fold!();
42
43    fn fold_prop_name(&mut self, n: PropName) -> PropName {
44        let n = n.fold_children_with(self);
45
46        match n {
47            PropName::Str(Str {
48                raw, value, span, ..
49            }) => {
50                if value.is_reserved() || !is_valid_ident(&value) {
51                    PropName::Str(Str { span, raw, value })
52                } else {
53                    PropName::Ident(IdentName::new(value, span))
54                }
55            }
56            PropName::Ident(i) => {
57                let IdentName { sym, span, .. } = i;
58                if sym.is_reserved() || sym.contains('-') || sym.contains('.') {
59                    PropName::Str(Str {
60                        span,
61                        raw: None,
62                        value: sym,
63                    })
64                } else {
65                    PropName::Ident(IdentName { span, sym })
66                }
67            }
68            _ => n,
69        }
70    }
71}
72
73#[cfg(test)]
74mod tests {
75    use swc_ecma_transforms_testing::test;
76
77    use super::*;
78
79    test!(
80        ::swc_ecma_parser::Syntax::default(),
81        |_| fold_pass(PropertyLiteral),
82        babel_basic,
83        r#"var foo = {
84  // changed
85  "bar": function () {},
86  "1": function () {},
87
88  // not changed
89  "default": 1,
90  [a]: 2,
91  foo: 1
92};"#,
93        ok_if_code_eq
94    );
95
96    test!(
97        ::swc_ecma_parser::Syntax::default(),
98        |_| fold_pass(PropertyLiteral),
99        str_lit,
100        r#"'use strict';
101var x = {
102    'foo.bar': true
103};"#,
104        ok_if_code_eq
105    );
106}