swc_ecma_compat_es3/
prop_lits.rs1use swc_ecma_ast::*;
2use swc_ecma_utils::{is_valid_ident, swc_atoms::Atom};
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 }) if value.as_str().is_some() => {
50 let v = value.as_str().unwrap();
51 if v.is_reserved() || !is_valid_ident(v) {
52 PropName::Str(Str { span, raw, value })
53 } else {
54 PropName::Ident(IdentName::new(
55 unsafe { Atom::from_wtf8_unchecked(value.clone()) },
57 span,
58 ))
59 }
60 }
61 PropName::Ident(i) => {
62 let IdentName { sym, span, .. } = i;
63 if sym.is_reserved() || sym.contains('-') || sym.contains('.') {
64 PropName::Str(Str {
65 span,
66 raw: None,
67 value: sym.into(),
68 })
69 } else {
70 PropName::Ident(IdentName { span, sym })
71 }
72 }
73 _ => n,
74 }
75 }
76}
77
78#[cfg(test)]
79mod tests {
80 use swc_ecma_transforms_testing::test;
81
82 use super::*;
83
84 test!(
85 ::swc_ecma_parser::Syntax::default(),
86 |_| fold_pass(PropertyLiteral),
87 babel_basic,
88 r#"var foo = {
89 // changed
90 "bar": function () {},
91 "1": function () {},
92
93 // not changed
94 "default": 1,
95 [a]: 2,
96 foo: 1
97};"#,
98 ok_if_code_eq
99 );
100
101 test!(
102 ::swc_ecma_parser::Syntax::default(),
103 |_| fold_pass(PropertyLiteral),
104 str_lit,
105 r#"'use strict';
106var x = {
107 'foo.bar': true
108};"#,
109 ok_if_code_eq
110 );
111}