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