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