1use is_macro::Is;
2use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span, DUMMY_SP};
3
4use crate::{
5    expr::Expr,
6    ident::{BindingIdent, Ident},
7    prop::PropName,
8    typescript::TsTypeAnn,
9    Id, IdentName, Invalid,
10};
11
12#[ast_node(no_clone)]
13#[derive(Eq, Hash, Is, EqIgnoreSpan)]
14#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
15#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
16pub enum Pat {
17    #[tag("Identifier")]
18    Ident(BindingIdent),
19
20    #[tag("ArrayPattern")]
21    Array(ArrayPat),
22
23    #[tag("RestElement")]
24    Rest(RestPat),
25
26    #[tag("ObjectPattern")]
27    Object(ObjectPat),
28
29    #[tag("AssignmentPattern")]
30    Assign(AssignPat),
31
32    #[tag("Invalid")]
33    Invalid(Invalid),
34
35    #[tag("*")]
37    Expr(Box<Expr>),
38}
39
40impl Clone for Pat {
43    fn clone(&self) -> Self {
44        use Pat::*;
45        match self {
46            #[cfg(all(swc_ast_unknown, feature = "encoding-impl"))]
47            Unknown(tag, v) => Unknown(*tag, v.clone()),
48            Ident(p) => Ident(p.clone()),
49            Array(p) => Array(p.clone()),
50            Rest(p) => Rest(p.clone()),
51            Object(p) => Object(p.clone()),
52            Assign(p) => Assign(p.clone()),
53            Invalid(p) => Invalid(p.clone()),
54            Expr(p) => Expr(p.clone()),
55        }
56    }
57}
58
59impl Default for Pat {
60    fn default() -> Self {
61        Invalid { span: DUMMY_SP }.into()
62    }
63}
64impl Take for Pat {
65    fn dummy() -> Self {
66        Default::default()
67    }
68}
69
70bridge_pat_from!(BindingIdent, Ident);
71bridge_pat_from!(BindingIdent, IdentName);
72bridge_pat_from!(BindingIdent, Id);
73
74macro_rules! pat_to_other {
75    ($T:ty) => {
76        bridge_from!(crate::Param, crate::Pat, $T);
77        bridge_from!(Box<crate::Pat>, crate::Pat, $T);
78    };
79}
80
81pat_to_other!(BindingIdent);
82pat_to_other!(ArrayPat);
83pat_to_other!(ObjectPat);
84pat_to_other!(AssignPat);
85pat_to_other!(RestPat);
86pat_to_other!(Box<Expr>);
87
88#[ast_node("ArrayPattern")]
89#[derive(Eq, Hash, EqIgnoreSpan)]
90#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
91#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
92pub struct ArrayPat {
93    pub span: Span,
94
95    #[cfg_attr(feature = "serde-impl", serde(rename = "elements"))]
96    #[cfg_attr(
97        feature = "encoding-impl",
98        encoding(with = "swc_common::serializer::ArrayOption")
99    )]
100    pub elems: Vec<Option<Pat>>,
101
102    #[cfg_attr(feature = "serde-impl", serde(rename = "optional"))]
104    pub optional: bool,
105
106    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeAnnotation"))]
107    #[cfg_attr(
108        feature = "encoding-impl",
109        encoding(with = "cbor4ii::core::types::Maybe")
110    )]
111    pub type_ann: Option<Box<TsTypeAnn>>,
112}
113
114#[ast_node("ObjectPattern")]
115#[derive(Eq, Hash, EqIgnoreSpan)]
116#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
117#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
118pub struct ObjectPat {
119    pub span: Span,
120
121    #[cfg_attr(feature = "serde-impl", serde(rename = "properties"))]
122    pub props: Vec<ObjectPatProp>,
123
124    #[cfg_attr(feature = "serde-impl", serde(rename = "optional"))]
126    pub optional: bool,
127
128    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeAnnotation"))]
129    #[cfg_attr(
130        feature = "encoding-impl",
131        encoding(with = "cbor4ii::core::types::Maybe")
132    )]
133    pub type_ann: Option<Box<TsTypeAnn>>,
134}
135
136#[ast_node("AssignmentPattern")]
137#[derive(Eq, Hash, EqIgnoreSpan)]
138#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
139#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
140pub struct AssignPat {
141    pub span: Span,
142
143    pub left: Box<Pat>,
144
145    pub right: Box<Expr>,
146}
147
148#[ast_node("RestElement")]
150#[derive(Eq, Hash, EqIgnoreSpan)]
151#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
152#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
153pub struct RestPat {
154    pub span: Span,
155
156    #[cfg_attr(feature = "serde-impl", serde(rename = "rest"))]
157    pub dot3_token: Span,
158
159    #[cfg_attr(feature = "serde-impl", serde(rename = "argument"))]
160    pub arg: Box<Pat>,
161
162    #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeAnnotation"))]
163    #[cfg_attr(
164        feature = "encoding-impl",
165        encoding(with = "cbor4ii::core::types::Maybe")
166    )]
167    pub type_ann: Option<Box<TsTypeAnn>>,
168}
169
170#[ast_node]
171#[derive(Eq, Hash, Is, EqIgnoreSpan)]
172#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
173#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
174pub enum ObjectPatProp {
175    #[tag("KeyValuePatternProperty")]
176    KeyValue(KeyValuePatProp),
177
178    #[tag("AssignmentPatternProperty")]
179    Assign(AssignPatProp),
180
181    #[tag("RestElement")]
182    Rest(RestPat),
183}
184
185#[ast_node("KeyValuePatternProperty")]
187#[derive(Eq, Hash, EqIgnoreSpan)]
188#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
189#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
190pub struct KeyValuePatProp {
191    #[span(lo)]
192    pub key: PropName,
193
194    #[span(hi)]
195    pub value: Box<Pat>,
196}
197#[ast_node("AssignmentPatternProperty")]
199#[derive(Eq, Hash, EqIgnoreSpan)]
200#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
201#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
202pub struct AssignPatProp {
203    pub span: Span,
204    pub key: BindingIdent,
207
208    #[cfg_attr(feature = "serde-impl", serde(default))]
209    #[cfg_attr(
210        feature = "encoding-impl",
211        encoding(with = "cbor4ii::core::types::Maybe")
212    )]
213    pub value: Option<Box<Expr>>,
214}