swc_ecma_compat_es3/
prop_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 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}