swc_ecma_compat_es2015/
shorthand_property.rs

1use swc_common::util::take::Take;
2use swc_ecma_ast::*;
3use swc_ecma_transforms_base::perf::Parallel;
4use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith};
5use swc_trace_macro::swc_trace;
6
7/// Compile ES2015 shorthand properties to ES5
8///
9///# Example
10///
11///## In
12///
13/// ```js
14/// var o = { a, b, c };
15/// ```
16///
17///## Out
18///
19/// ```js
20/// var o = { a: a, b: b, c: c };
21/// ```
22///
23///## In
24///
25/// ```js
26/// var cat = {
27///   getName() {
28///     return name;
29///   }
30/// };
31/// ```
32///
33///## Out
34///```js
35/// var cat = {
36///   getName: function () {
37///     return name;
38///   }
39/// };
40/// ```
41pub fn shorthand() -> impl Pass {
42    visit_mut_pass(Shorthand)
43}
44
45#[derive(Clone, Copy)]
46struct Shorthand;
47
48impl Parallel for Shorthand {
49    fn create(&self) -> Self {
50        *self
51    }
52
53    fn merge(&mut self, _: Self) {}
54}
55
56#[swc_trace]
57impl VisitMut for Shorthand {
58    noop_visit_mut_type!(fail);
59
60    fn visit_mut_prop(&mut self, prop: &mut Prop) {
61        prop.visit_mut_children_with(self);
62
63        match prop {
64            Prop::Shorthand(ident) => {
65                let value = ident.clone().into();
66
67                *prop = Prop::KeyValue(KeyValueProp {
68                    key: if ident.sym == "__proto__" {
69                        PropName::Computed(ComputedPropName {
70                            span: ident.span,
71                            expr: ident.sym.clone().into(),
72                        })
73                    } else {
74                        ident.take().into()
75                    },
76                    value,
77                });
78            }
79            Prop::Method(MethodProp { key, function }) => {
80                let key = match key.take() {
81                    PropName::Ident(IdentName { span, sym, .. }) if sym == "__proto__" => {
82                        ComputedPropName {
83                            span,
84                            expr: sym.into(),
85                        }
86                        .into()
87                    }
88                    PropName::Str(s @ Str { span, .. }) if s.value == "__proto__" => {
89                        ComputedPropName {
90                            span,
91                            expr: s.into(),
92                        }
93                        .into()
94                    }
95                    key => key,
96                };
97                *prop = Prop::KeyValue(KeyValueProp {
98                    key,
99                    value: FnExpr {
100                        ident: None,
101                        function: function.take(),
102                    }
103                    .into(),
104                })
105            }
106            _ => {}
107        }
108    }
109}