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            #[cfg(swc_ast_unknown)]
65            _ => panic!("unable to access unknown nodes"),
66        }
67    }
68}
69
70impl Babelify for ClassProp {
71    type Output = ClassProperty;
72
73    fn babelify(self, ctx: &Context) -> Self::Output {
74        let computed = Some(self.key.is_computed());
75
76        ClassProperty {
77            base: ctx.base(self.span),
78            key: self.key.babelify(ctx),
79            value: self
80                .value
81                .map(|val| Box::alloc().init(val.babelify(ctx).into())),
82            type_annotation: self
83                .type_ann
84                .map(|ann| Box::alloc().init(ann.babelify(ctx).into())),
85            is_static: Some(self.is_static),
86            decorators: Some(self.decorators.babelify(ctx)),
87            computed,
88            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
89            is_abstract: Some(self.is_abstract),
90            optional: Some(self.is_optional),
91            readonly: Some(self.readonly),
92            declare: Some(self.declare),
93            definite: Some(self.definite),
94        }
95    }
96}
97
98impl Babelify for PrivateProp {
99    type Output = ClassPrivateProperty;
100
101    fn babelify(self, ctx: &Context) -> Self::Output {
102        ClassPrivateProperty {
103            base: ctx.base(self.span),
104            key: self.key.babelify(ctx),
105            value: self
106                .value
107                .map(|expr| Box::alloc().init(expr.babelify(ctx).into())),
108            type_annotation: self
109                .type_ann
110                .map(|ann| Box::alloc().init(ann.babelify(ctx).into())),
111            static_any: Value::Bool(self.is_static),
112            decorators: Some(self.decorators.babelify(ctx)),
113        }
114    }
115}
116
117impl Babelify for ClassMethod {
118    type Output = BabelClassMethod;
119
120    fn babelify(self, ctx: &Context) -> Self::Output {
121        BabelClassMethod {
122            base: ctx.base(self.span),
123            key: self.key.babelify(ctx),
124            kind: Some(self.kind.babelify(ctx)),
125            is_static: Some(self.is_static),
126            access: self.accessibility.map(|access| access.babelify(ctx)),
127            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
128            is_abstract: Some(self.is_abstract),
129            optional: Some(self.is_optional),
130            params: self.function.params.babelify(ctx),
131            body: self.function.body.unwrap().babelify(ctx),
132            generator: Some(self.function.is_generator),
133            is_async: Some(self.function.is_async),
134            decorators: Some(self.function.decorators.babelify(ctx)),
135            type_parameters: self.function.type_params.map(|t| t.babelify(ctx).into()),
136            return_type: self
137                .function
138                .return_type
139                .map(|t| Box::alloc().init(t.babelify(ctx).into())),
140            computed: Default::default(),
141        }
142    }
143}
144
145impl Babelify for PrivateMethod {
146    type Output = ClassPrivateMethod;
147
148    fn babelify(self, ctx: &Context) -> Self::Output {
149        ClassPrivateMethod {
150            base: ctx.base(self.span),
151            key: self.key.babelify(ctx),
152            kind: Some(self.kind.babelify(ctx)),
153            is_static: Some(self.is_static),
154            access: self.accessibility.map(|access| access.babelify(ctx)),
155            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
156            is_abstract: Some(self.is_abstract),
157            optional: Some(self.is_optional),
158            params: self.function.params.babelify(ctx),
159            body: self.function.body.unwrap().babelify(ctx),
160            generator: Some(self.function.is_generator),
161            is_async: Some(self.function.is_async),
162            decorators: Some(self.function.decorators.babelify(ctx)),
163            type_parameters: self.function.type_params.map(|t| t.babelify(ctx).into()),
164            return_type: self
165                .function
166                .return_type
167                .map(|t| Box::alloc().init(t.babelify(ctx).into())),
168            computed: Default::default(),
169        }
170    }
171}
172
173impl Babelify for Constructor {
174    type Output = BabelClassMethod;
175
176    fn babelify(self, ctx: &Context) -> Self::Output {
177        BabelClassMethod {
178            base: ctx.base(self.span),
179            kind: Some(ClassMethodKind::Constructor),
180            key: self.key.babelify(ctx),
181            params: self.params.babelify(ctx),
182            body: self.body.unwrap().babelify(ctx),
183            access: self.accessibility.map(|access| access.babelify(ctx)),
184            accessibility: self.accessibility.map(|access| access.babelify(ctx)),
185            optional: Some(self.is_optional),
186            computed: Default::default(),
187            is_static: Default::default(),
188            generator: Default::default(),
189            is_async: Default::default(),
190            is_abstract: Default::default(),
191            decorators: Default::default(),
192            return_type: Default::default(),
193            type_parameters: Default::default(),
194        }
195    }
196}
197
198impl Babelify for Decorator {
199    type Output = BabelDecorator;
200
201    fn babelify(self, ctx: &Context) -> Self::Output {
202        BabelDecorator {
203            base: ctx.base(self.span),
204            expression: Box::alloc().init(self.expr.babelify(ctx).into()),
205        }
206    }
207}
208
209impl Babelify for MethodKind {
210    type Output = ClassMethodKind;
211
212    fn babelify(self, _ctx: &Context) -> Self::Output {
213        match self {
214            MethodKind::Method => ClassMethodKind::Method,
215            MethodKind::Getter => ClassMethodKind::Get,
216            MethodKind::Setter => ClassMethodKind::Set,
217            #[cfg(swc_ast_unknown)]
218            _ => panic!("unable to access unknown nodes"),
219        }
220    }
221}
222
223impl Babelify for StaticBlock {
224    type Output = BabelStaticBlock;
225
226    fn babelify(self, ctx: &Context) -> Self::Output {
227        BabelStaticBlock {
228            base: ctx.base(self.span),
229            body: self.body.stmts.babelify(ctx),
230        }
231    }
232}