1use is_macro::Is;
2use swc_atoms::Atom;
3use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span, DUMMY_SP};
4
5use crate::{
6 expr::{Expr, SpreadElement},
7 ident::Ident,
8 lit::Lit,
9 typescript::TsTypeParamInstantiation,
10 IdentName,
11};
12
13#[ast_node]
15#[derive(Eq, Hash, Is, EqIgnoreSpan)]
16#[allow(variant_size_differences)]
17#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
18#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
19pub enum JSXObject {
20 #[tag("JSXMemberExpression")]
21 JSXMemberExpr(Box<JSXMemberExpr>),
22 #[tag("Identifier")]
23 Ident(Ident),
24}
25
26#[ast_node("JSXMemberExpression")]
27#[derive(Eq, Hash, EqIgnoreSpan)]
28#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
29#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
30pub struct JSXMemberExpr {
31 pub span: Span,
32
33 #[cfg_attr(feature = "serde-impl", serde(rename = "object"))]
34 pub obj: JSXObject,
35
36 #[cfg_attr(feature = "serde-impl", serde(rename = "property"))]
37 pub prop: IdentName,
38}
39
40#[ast_node("JSXNamespacedName")]
42#[derive(Eq, Hash, EqIgnoreSpan)]
43#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
44#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
45pub struct JSXNamespacedName {
46 pub span: Span,
47 #[cfg_attr(feature = "serde-impl", serde(rename = "namespace"))]
48 pub ns: IdentName,
49 pub name: IdentName,
50}
51
52#[ast_node("JSXEmptyExpression")]
53#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
54#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
55#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
56pub struct JSXEmptyExpr {
57 pub span: Span,
58}
59
60#[ast_node("JSXExpressionContainer")]
61#[derive(Eq, Hash, EqIgnoreSpan)]
62#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
63#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
64pub struct JSXExprContainer {
65 pub span: Span,
66 #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
67 pub expr: JSXExpr,
68}
69
70#[ast_node]
71#[derive(Eq, Hash, EqIgnoreSpan)]
72#[allow(variant_size_differences)]
73#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
74#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
75pub enum JSXExpr {
76 #[tag("JSXEmptyExpression")]
77 JSXEmptyExpr(JSXEmptyExpr),
78 #[tag("*")]
79 Expr(Box<Expr>),
80}
81
82#[ast_node("JSXSpreadChild")]
83#[derive(Eq, Hash, EqIgnoreSpan)]
84#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
85#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
86pub struct JSXSpreadChild {
87 pub span: Span,
88 #[cfg_attr(feature = "serde-impl", serde(rename = "expression"))]
89 pub expr: Box<Expr>,
90}
91
92#[ast_node]
93#[derive(Eq, Hash, EqIgnoreSpan)]
94#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
95#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
96pub enum JSXElementName {
97 #[tag("Identifier")]
98 Ident(Ident),
99 #[tag("JSXMemberExpression")]
100 JSXMemberExpr(JSXMemberExpr),
101 #[tag("JSXNamespacedName")]
102 JSXNamespacedName(JSXNamespacedName),
103}
104
105impl Take for JSXElementName {
106 fn dummy() -> Self {
107 JSXElementName::Ident(Take::dummy())
108 }
109}
110
111#[ast_node("JSXOpeningElement")]
112#[derive(Eq, Hash, EqIgnoreSpan)]
113#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
114#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
115pub struct JSXOpeningElement {
116 pub name: JSXElementName,
117
118 pub span: Span,
119
120 #[cfg_attr(feature = "serde-impl", serde(default, rename = "attributes"))]
121 pub attrs: Vec<JSXAttrOrSpread>,
122
123 #[cfg_attr(feature = "serde-impl", serde(rename = "selfClosing"))]
124 pub self_closing: bool,
125
126 #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeArguments"))]
129 pub type_args: Option<Box<TsTypeParamInstantiation>>,
130}
131
132impl Take for JSXOpeningElement {
133 fn dummy() -> Self {
134 JSXOpeningElement {
135 name: Take::dummy(),
136 span: DUMMY_SP,
137 attrs: Take::dummy(),
138 self_closing: Default::default(),
139 type_args: Take::dummy(),
140 }
141 }
142}
143
144#[ast_node]
145#[derive(Eq, Hash, EqIgnoreSpan)]
146#[allow(variant_size_differences)]
147#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
148#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
149pub enum JSXAttrOrSpread {
150 #[tag("JSXAttribute")]
151 JSXAttr(JSXAttr),
152 #[tag("SpreadElement")]
153 SpreadElement(SpreadElement),
154}
155
156#[ast_node("JSXClosingElement")]
157#[derive(Eq, Hash, EqIgnoreSpan)]
158#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
159#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
160pub struct JSXClosingElement {
161 pub span: Span,
162 pub name: JSXElementName,
163}
164
165#[ast_node("JSXAttribute")]
166#[derive(Eq, Hash, EqIgnoreSpan)]
167#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
168#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
169pub struct JSXAttr {
170 pub span: Span,
171 pub name: JSXAttrName,
172 pub value: Option<JSXAttrValue>,
174}
175
176#[ast_node]
177#[derive(Eq, Hash, EqIgnoreSpan)]
178#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
179#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
180pub enum JSXAttrName {
181 #[tag("Identifier")]
182 Ident(IdentName),
183 #[tag("JSXNamespacedName")]
184 JSXNamespacedName(JSXNamespacedName),
185}
186
187#[ast_node]
188#[derive(Eq, Hash, EqIgnoreSpan)]
189#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
190#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
191pub enum JSXAttrValue {
192 #[tag("StringLiteral")]
193 #[tag("BooleanLiteral")]
194 #[tag("NullLiteral")]
195 #[tag("NumericLiteral")]
196 #[tag("RegExpLiteral")]
197 #[tag("JSXText")]
198 Lit(Lit),
199
200 #[tag("JSXExpressionContainer")]
201 JSXExprContainer(JSXExprContainer),
202
203 #[tag("JSXElement")]
204 JSXElement(Box<JSXElement>),
205
206 #[tag("JSXFragment")]
207 JSXFragment(JSXFragment),
208}
209
210#[ast_node("JSXText")]
211#[derive(Eq, Hash, EqIgnoreSpan)]
212#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
213pub struct JSXText {
214 pub span: Span,
215 pub value: Atom,
216 pub raw: Atom,
217}
218
219#[cfg(feature = "arbitrary")]
220#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
221impl<'a> arbitrary::Arbitrary<'a> for JSXText {
222 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
223 let span = u.arbitrary()?;
224 let value = u.arbitrary::<String>()?.into();
225 let raw = u.arbitrary::<String>()?.into();
226
227 Ok(Self { span, value, raw })
228 }
229}
230
231#[ast_node("JSXElement")]
232#[derive(Eq, Hash, EqIgnoreSpan)]
233#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
234#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
235pub struct JSXElement {
236 pub span: Span,
237 pub opening: JSXOpeningElement,
238 pub children: Vec<JSXElementChild>,
239 pub closing: Option<JSXClosingElement>,
240}
241
242impl Take for JSXElement {
243 fn dummy() -> Self {
244 JSXElement {
245 span: DUMMY_SP,
246 opening: Take::dummy(),
247 children: Take::dummy(),
248 closing: Take::dummy(),
249 }
250 }
251}
252
253#[ast_node]
254#[derive(Eq, Hash, EqIgnoreSpan)]
255#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
256#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
257pub enum JSXElementChild {
258 #[tag("JSXText")]
259 JSXText(JSXText),
260
261 #[tag("JSXExpressionContainer")]
262 JSXExprContainer(JSXExprContainer),
263
264 #[tag("JSXSpreadChild")]
265 JSXSpreadChild(JSXSpreadChild),
266
267 #[tag("JSXElement")]
268 JSXElement(Box<JSXElement>),
269
270 #[tag("JSXFragment")]
271 JSXFragment(JSXFragment),
272}
273
274#[ast_node("JSXFragment")]
275#[derive(Eq, Hash, EqIgnoreSpan)]
276#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
277#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
278pub struct JSXFragment {
279 pub span: Span,
280
281 pub opening: JSXOpeningFragment,
282
283 #[cfg_attr(feature = "serde-impl", serde(default))]
284 pub children: Vec<JSXElementChild>,
285
286 pub closing: JSXClosingFragment,
287}
288
289impl Take for JSXFragment {
290 fn dummy() -> Self {
291 JSXFragment {
292 span: DUMMY_SP,
293 opening: Take::dummy(),
294 children: Take::dummy(),
295 closing: Take::dummy(),
296 }
297 }
298}
299
300#[ast_node("JSXOpeningFragment")]
301#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
302#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
303#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
304pub struct JSXOpeningFragment {
305 pub span: Span,
306}
307
308impl Take for JSXOpeningFragment {
309 fn dummy() -> Self {
310 JSXOpeningFragment { span: DUMMY_SP }
311 }
312}
313
314#[ast_node("JSXClosingFragment")]
315#[derive(Eq, Hash, Copy, EqIgnoreSpan)]
316#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
317#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
318pub struct JSXClosingFragment {
319 pub span: Span,
320}
321
322impl Take for JSXClosingFragment {
323 fn dummy() -> Self {
324 JSXClosingFragment { span: DUMMY_SP }
325 }
326}