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, .. })
89                        if s.value.as_str() == Some("__proto__") =>
90                    {
91                        ComputedPropName {
92                            span,
93                            expr: s.into(),
94                        }
95                        .into()
96                    }
97                    key => key,
98                };
99                *prop = Prop::KeyValue(KeyValueProp {
100                    key,
101                    value: FnExpr {
102                        ident: None,
103                        function: function.take(),
104                    }
105                    .into(),
106                })
107            }
108            _ => {}
109        }
110    }
111}