swc_estree_compat/babelify/
pat.rs

1use copyless::BoxHelper;
2use serde::{Deserialize, Serialize};
3use swc_common::Spanned;
4use swc_ecma_ast::{
5    ArrayPat, AssignPat, AssignPatProp, KeyValuePatProp, ObjectPat, ObjectPatProp, Pat, RestPat,
6};
7use swc_estree_ast::{
8    ArrayPattern, AssignmentPattern, AssignmentPatternLeft, CatchClauseParam, Expression,
9    Identifier, LVal, ObjectKey, ObjectPattern, ObjectPatternProp, ObjectPropVal, ObjectProperty,
10    Param, Pattern, PatternLike, RestElement,
11};
12
13use crate::babelify::{Babelify, Context};
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub enum PatOutput {
17    Id(Identifier),
18    Array(ArrayPattern),
19    Rest(RestElement),
20    Object(ObjectPattern),
21    Assign(AssignmentPattern),
22    Expr(Box<Expression>),
23}
24
25impl Babelify for Pat {
26    type Output = PatOutput;
27
28    fn babelify(self, ctx: &Context) -> Self::Output {
29        match self {
30            Pat::Ident(i) => PatOutput::Id(i.babelify(ctx)),
31            Pat::Array(a) => PatOutput::Array(a.babelify(ctx)),
32            Pat::Rest(r) => PatOutput::Rest(r.babelify(ctx)),
33            Pat::Object(o) => PatOutput::Object(o.babelify(ctx)),
34            Pat::Assign(a) => PatOutput::Assign(a.babelify(ctx)),
35            Pat::Expr(e) => PatOutput::Expr(Box::alloc().init(e.babelify(ctx).into())),
36            Pat::Invalid(_) => panic!(
37                "illegal conversion: Cannot convert {:?} to PatOutput",
38                &self
39            ),
40        }
41    }
42}
43
44impl From<PatOutput> for Pattern {
45    fn from(pat: PatOutput) -> Self {
46        match pat {
47            PatOutput::Assign(a) => Pattern::Assignment(a),
48            PatOutput::Array(a) => Pattern::Array(a),
49            PatOutput::Object(o) => Pattern::Object(o),
50            _ => panic!("illegal conversion: Cannot convert {:?} to Pattern", &pat),
51        }
52    }
53}
54
55impl From<PatOutput> for ObjectPropVal {
56    fn from(pat: PatOutput) -> Self {
57        match pat {
58            PatOutput::Expr(e) => ObjectPropVal::Expr(e),
59            PatOutput::Id(p) => ObjectPropVal::Pattern(PatternLike::Id(p)),
60            PatOutput::Array(p) => ObjectPropVal::Pattern(PatternLike::ArrayPat(p)),
61            PatOutput::Rest(p) => ObjectPropVal::Pattern(PatternLike::RestEl(p)),
62            PatOutput::Object(p) => ObjectPropVal::Pattern(PatternLike::ObjectPat(p)),
63            PatOutput::Assign(p) => ObjectPropVal::Pattern(PatternLike::AssignmentPat(p)),
64        }
65    }
66}
67
68impl From<PatOutput> for LVal {
69    fn from(pat: PatOutput) -> Self {
70        match pat {
71            PatOutput::Id(i) => LVal::Id(i),
72            PatOutput::Array(a) => LVal::ArrayPat(a),
73            PatOutput::Rest(r) => LVal::RestEl(r),
74            PatOutput::Object(o) => LVal::ObjectPat(o),
75            PatOutput::Assign(a) => LVal::AssignmentPat(a),
76            PatOutput::Expr(expr) => match *expr {
77                Expression::Member(e) => LVal::MemberExpr(e),
78                _ => panic!("illegal conversion: Cannot convert {:?} to LVal", &expr),
79            },
80        }
81    }
82}
83
84impl From<PatOutput> for PatternLike {
85    fn from(pat: PatOutput) -> Self {
86        match pat {
87            PatOutput::Id(i) => PatternLike::Id(i),
88            PatOutput::Array(a) => PatternLike::ArrayPat(a),
89            PatOutput::Rest(r) => PatternLike::RestEl(r),
90            PatOutput::Object(o) => PatternLike::ObjectPat(o),
91            PatOutput::Assign(a) => PatternLike::AssignmentPat(a),
92            PatOutput::Expr(_) => panic!("illegal conversion: Cannot convert {:?} to LVal", &pat),
93        }
94    }
95}
96
97impl From<PatOutput> for AssignmentPatternLeft {
98    fn from(pat: PatOutput) -> Self {
99        match pat {
100            PatOutput::Id(i) => AssignmentPatternLeft::Id(i),
101            PatOutput::Array(a) => AssignmentPatternLeft::Array(a),
102            PatOutput::Object(o) => AssignmentPatternLeft::Object(o),
103            PatOutput::Expr(expr) => match *expr {
104                Expression::Member(e) => AssignmentPatternLeft::Member(e),
105                _ => panic!(
106                    "illegal conversion: Cannot convert {:?} to AssignmentPatternLeft",
107                    &expr
108                ),
109            },
110            PatOutput::Rest(_) => panic!(
111                "illegal conversion: Cannot convert {:?} to AssignmentPatternLeft",
112                &pat
113            ),
114            PatOutput::Assign(_) => panic!(
115                "illegal conversion: Cannot convert {:?} to AssignmentPatternLeft",
116                &pat
117            ),
118        }
119    }
120}
121
122impl From<PatOutput> for Param {
123    fn from(pat: PatOutput) -> Self {
124        match pat {
125            PatOutput::Id(i) => Param::Id(i),
126            PatOutput::Rest(r) => Param::Rest(r),
127            PatOutput::Array(p) => Param::Pat(Pattern::Array(p)),
128            PatOutput::Object(p) => Param::Pat(Pattern::Object(p)),
129            PatOutput::Assign(p) => Param::Pat(Pattern::Assignment(p)),
130            PatOutput::Expr(p) => panic!("Cannot convert {p:?} to Param"),
131        }
132    }
133}
134
135impl From<PatOutput> for CatchClauseParam {
136    fn from(pat: PatOutput) -> Self {
137        match pat {
138            PatOutput::Id(i) => CatchClauseParam::Id(i),
139            PatOutput::Array(a) => CatchClauseParam::Array(a),
140            PatOutput::Object(o) => CatchClauseParam::Object(o),
141            _ => panic!(
142                "illegal conversion: Cannot convert {:?} to CatchClauseParam",
143                &pat
144            ),
145        }
146    }
147}
148
149impl Babelify for ArrayPat {
150    type Output = ArrayPattern;
151
152    fn babelify(self, ctx: &Context) -> Self::Output {
153        ArrayPattern {
154            base: ctx.base(self.span),
155            elements: self
156                .elems
157                .into_iter()
158                .map(|opt| opt.map(|e| e.babelify(ctx).into()))
159                .collect(),
160            type_annotation: self
161                .type_ann
162                .map(|a| Box::alloc().init(a.babelify(ctx).into())),
163            decorators: Default::default(),
164        }
165    }
166}
167
168impl Babelify for ObjectPat {
169    type Output = ObjectPattern;
170
171    fn babelify(self, ctx: &Context) -> Self::Output {
172        ObjectPattern {
173            base: ctx.base(self.span),
174            properties: self.props.babelify(ctx),
175            type_annotation: self
176                .type_ann
177                .map(|a| Box::alloc().init(a.babelify(ctx).into())),
178            decorators: Default::default(),
179        }
180    }
181}
182
183impl Babelify for ObjectPatProp {
184    type Output = ObjectPatternProp;
185
186    fn babelify(self, ctx: &Context) -> Self::Output {
187        match self {
188            ObjectPatProp::KeyValue(p) => ObjectPatternProp::Prop(p.babelify(ctx)),
189            ObjectPatProp::Rest(r) => ObjectPatternProp::Rest(r.babelify(ctx)),
190            ObjectPatProp::Assign(a) => ObjectPatternProp::Prop(a.babelify(ctx)),
191        }
192    }
193}
194
195impl Babelify for KeyValuePatProp {
196    type Output = ObjectProperty;
197
198    fn babelify(self, ctx: &Context) -> Self::Output {
199        ObjectProperty {
200            base: ctx.base(self.span()),
201            key: self.key.babelify(ctx),
202            value: self.value.babelify(ctx).into(),
203            computed: Default::default(),
204            shorthand: Default::default(),
205            decorators: Default::default(),
206        }
207    }
208}
209
210impl Babelify for RestPat {
211    type Output = RestElement;
212
213    fn babelify(self, ctx: &Context) -> Self::Output {
214        RestElement {
215            base: ctx.base(self.span),
216            argument: Box::alloc().init(self.arg.babelify(ctx).into()),
217            type_annotation: self
218                .type_ann
219                .map(|a| Box::alloc().init(a.babelify(ctx).into())),
220            decorators: Default::default(),
221        }
222    }
223}
224
225impl Babelify for AssignPat {
226    type Output = AssignmentPattern;
227
228    fn babelify(self, ctx: &Context) -> Self::Output {
229        AssignmentPattern {
230            base: ctx.base(self.span),
231            left: self.left.babelify(ctx).into(),
232            right: Box::alloc().init(self.right.babelify(ctx).into()),
233            type_annotation: None,
234            decorators: Default::default(),
235        }
236    }
237}
238
239impl Babelify for AssignPatProp {
240    type Output = ObjectProperty;
241
242    fn babelify(self, ctx: &Context) -> Self::Output {
243        let is_shorthand = self.value.is_none();
244        ObjectProperty {
245            base: ctx.base(self.span),
246            key: ObjectKey::Id(self.key.clone().babelify(ctx)),
247            value: if is_shorthand {
248                ObjectPropVal::Pattern(PatternLike::Id(self.key.babelify(ctx)))
249            } else {
250                ObjectPropVal::Expr(Box::alloc().init(self.value.unwrap().babelify(ctx).into()))
251            },
252            shorthand: is_shorthand,
253            computed: Default::default(),
254            decorators: Default::default(),
255        }
256    }
257}