swc_estree_compat/babelify/
class.rs

1use copyless::BoxHelper;
2use serde_json::value::Value;
3use swc_ecma_ast::{
4    Class, ClassMember, ClassMethod, ClassProp, Constructor, Decorator, MethodKind, PrivateMethod,
5    PrivateProp, StaticBlock,
6};
7use swc_estree_ast::{
8    ClassBody, ClassBodyEl, ClassExpression, ClassMethod as BabelClassMethod, ClassMethodKind,
9    ClassPrivateMethod, ClassPrivateProperty, ClassProperty, Decorator as BabelDecorator,
10    StaticBlock as BabelStaticBlock,
11};
12
13use crate::babelify::{extract_class_body_span, Babelify, Context};
14
15impl Babelify for Class {
16    type Output = ClassExpression;
17
18    fn babelify(self, ctx: &Context) -> Self::Output {
19        let body = ClassBody {
20            base: ctx.base(extract_class_body_span(&self, ctx)),
21            body: self.body.babelify(ctx),
22        };
23
24        ClassExpression {
25            base: ctx.base(self.span),
26            decorators: Some(self.decorators.babelify(ctx)),
27            body,
28            super_class: self
29                .super_class
30                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
31            type_parameters: self.type_params.map(|param| param.babelify(ctx).into()),
32            super_type_parameters: self
33                .super_type_params
34                .map(|param| param.babelify(ctx).into()),
35            implements: Some(
36                self.implements
37                    .into_iter()
38                    .map(|imp| imp.babelify(ctx).into())
39                    .collect(),
40            ),
41            id: Default::default(),
42            mixins: Default::default(),
43        }
44    }
45}
46
47impl Babelify for ClassMember {
48    type Output = ClassBodyEl;
49
50    fn babelify(self, ctx: &Context) -> Self::Output {
51        match self {
52            ClassMember::Constructor(c) => ClassBodyEl::Method(c.babelify(ctx)),
53            ClassMember::Method(m) => ClassBodyEl::Method(m.babelify(ctx)),
54            ClassMember::PrivateMethod(m) => ClassBodyEl::PrivateMethod(m.babelify(ctx)),
55            ClassMember::ClassProp(p) => ClassBodyEl::Prop(p.babelify(ctx)),
56            ClassMember::PrivateProp(p) => ClassBodyEl::PrivateProp(p.babelify(ctx)),
57            ClassMember::TsIndexSignature(s) => ClassBodyEl::TSIndex(s.babelify(ctx)),
58            ClassMember::Empty(_) => panic!(
59                "illegal conversion: Cannot convert {:?} to ClassBodyEl",
60                &self
61            ),
62            ClassMember::StaticBlock(s) => ClassBodyEl::StaticBlock(s.babelify(ctx)),
63            ClassMember::AutoAccessor(..) => todo!("auto accessor"),
64        }
65    }
66}
67
68impl Babelify for ClassProp {
69    type Output = ClassProperty;
70
71    fn babelify(self, ctx: &Context) -> Self::Output {
72        let computed = Some(self.key.is_computed());
73
74        ClassProperty {
75            base: ctx.base(self.span),
76            key: self.key.babelify(ctx),
77            value: self
78                .value
79                .map(|val| Box::alloc().init(val.babelify(ctx).into())),
80            type_annotation: self
81                .type_ann
82                .map(|ann| Box::alloc().init(ann.babelify(ctx).into())),
83            is_static: Some(self.is_static),
84            decorators: Some(self.decorators.babelify(ctx)),
85            computed,
86            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
87            is_abstract: Some(self.is_abstract),
88            optional: Some(self.is_optional),
89            readonly: Some(self.readonly),
90            declare: Some(self.declare),
91            definite: Some(self.definite),
92        }
93    }
94}
95
96impl Babelify for PrivateProp {
97    type Output = ClassPrivateProperty;
98
99    fn babelify(self, ctx: &Context) -> Self::Output {
100        ClassPrivateProperty {
101            base: ctx.base(self.span),
102            key: self.key.babelify(ctx),
103            value: self
104                .value
105                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
106            type_annotation: self
107                .type_ann
108                .map(|ann| Box::alloc().init(ann.babelify(ctx).into())),
109            static_any: Value::Bool(self.is_static),
110            decorators: Some(self.decorators.babelify(ctx)),
111        }
112    }
113}
114
115impl Babelify for ClassMethod {
116    type Output = BabelClassMethod;
117
118    fn babelify(self, ctx: &Context) -> Self::Output {
119        BabelClassMethod {
120            base: ctx.base(self.span),
121            key: self.key.babelify(ctx),
122            kind: Some(self.kind.babelify(ctx)),
123            is_static: Some(self.is_static),
124            access: self.accessibility.map(|access| access.babelify(ctx)),
125            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
126            is_abstract: Some(self.is_abstract),
127            optional: Some(self.is_optional),
128            params: self.function.params.babelify(ctx),
129            body: self.function.body.unwrap().babelify(ctx),
130            generator: Some(self.function.is_generator),
131            is_async: Some(self.function.is_async),
132            decorators: Some(self.function.decorators.babelify(ctx)),
133            type_parameters: self.function.type_params.map(|t| t.babelify(ctx).into()),
134            return_type: self
135                .function
136                .return_type
137                .map(|t| Box::alloc().init(t.babelify(ctx).into())),
138            computed: Default::default(),
139        }
140    }
141}
142
143impl Babelify for PrivateMethod {
144    type Output = ClassPrivateMethod;
145
146    fn babelify(self, ctx: &Context) -> Self::Output {
147        ClassPrivateMethod {
148            base: ctx.base(self.span),
149            key: self.key.babelify(ctx),
150            kind: Some(self.kind.babelify(ctx)),
151            is_static: Some(self.is_static),
152            access: self.accessibility.map(|access| access.babelify(ctx)),
153            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
154            is_abstract: Some(self.is_abstract),
155            optional: Some(self.is_optional),
156            params: self.function.params.babelify(ctx),
157            body: self.function.body.unwrap().babelify(ctx),
158            generator: Some(self.function.is_generator),
159            is_async: Some(self.function.is_async),
160            decorators: Some(self.function.decorators.babelify(ctx)),
161            type_parameters: self.function.type_params.map(|t| t.babelify(ctx).into()),
162            return_type: self
163                .function
164                .return_type
165                .map(|t| Box::alloc().init(t.babelify(ctx).into())),
166            computed: Default::default(),
167        }
168    }
169}
170
171impl Babelify for Constructor {
172    type Output = BabelClassMethod;
173
174    fn babelify(self, ctx: &Context) -> Self::Output {
175        BabelClassMethod {
176            base: ctx.base(self.span),
177            kind: Some(ClassMethodKind::Constructor),
178            key: self.key.babelify(ctx),
179            params: self.params.babelify(ctx),
180            body: self.body.unwrap().babelify(ctx),
181            access: self.accessibility.map(|access| access.babelify(ctx)),
182            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
183            optional: Some(self.is_optional),
184            computed: Default::default(),
185            is_static: Default::default(),
186            generator: Default::default(),
187            is_async: Default::default(),
188            is_abstract: Default::default(),
189            decorators: Default::default(),
190            return_type: Default::default(),
191            type_parameters: Default::default(),
192        }
193    }
194}
195
196impl Babelify for Decorator {
197    type Output = BabelDecorator;
198
199    fn babelify(self, ctx: &Context) -> Self::Output {
200        BabelDecorator {
201            base: ctx.base(self.span),
202            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
203        }
204    }
205}
206
207impl Babelify for MethodKind {
208    type Output = ClassMethodKind;
209
210    fn babelify(self, _ctx: &Context) -> Self::Output {
211        match self {
212            MethodKind::Method => ClassMethodKind::Method,
213            MethodKind::Getter => ClassMethodKind::Get,
214            MethodKind::Setter => ClassMethodKind::Set,
215        }
216    }
217}
218
219impl Babelify for StaticBlock {
220    type Output = BabelStaticBlock;
221
222    fn babelify(self, ctx: &Context) -> Self::Output {
223        BabelStaticBlock {
224            base: ctx.base(self.span),
225            body: self.body.stmts.babelify(ctx),
226        }
227    }
228}