swc_ecma_codegen/
jsx.rs

1use swc_common::{BytePos, SourceMapper, Spanned};
2use swc_ecma_ast::*;
3use swc_ecma_codegen_macros::node_impl;
4
5use super::Emitter;
6use crate::text_writer::WriteJs;
7#[cfg(swc_ast_unknown)]
8use crate::unknown_error;
9
10impl<W, S: SourceMapper> Emitter<'_, W, S>
11where
12    W: WriteJs,
13    S: SourceMapperExt,
14{
15}
16
17#[node_impl]
18impl MacroNode for JSXElement {
19    fn emit(&mut self, emitter: &mut Macro) -> Result {
20        emit!(self.opening);
21        emitter.emit_list(
22            self.span(),
23            Some(&self.children),
24            ListFormat::JsxElementOrFragmentChildren,
25        )?;
26        if let Some(ref closing) = self.closing {
27            emit!(closing)
28        }
29        Ok(())
30    }
31}
32
33#[node_impl]
34impl MacroNode for JSXOpeningElement {
35    fn emit(&mut self, emitter: &mut Macro) -> Result {
36        punct!(emitter, "<");
37        emit!(self.name);
38
39        if let Some(type_args) = &self.type_args {
40            emit!(type_args);
41        }
42
43        if !self.attrs.is_empty() {
44            space!(emitter);
45
46            emitter.emit_list(
47                self.span(),
48                Some(&self.attrs),
49                ListFormat::JsxElementAttributes,
50            )?;
51        }
52
53        if self.self_closing {
54            punct!(emitter, "/");
55        }
56        punct!(emitter, ">");
57        Ok(())
58    }
59}
60
61#[node_impl]
62impl MacroNode for JSXElementName {
63    fn emit(&mut self, emitter: &mut Macro) -> Result {
64        match *self {
65            JSXElementName::Ident(ref n) => emit!(n),
66            JSXElementName::JSXMemberExpr(ref n) => emit!(n),
67            JSXElementName::JSXNamespacedName(ref n) => emit!(n),
68            #[cfg(swc_ast_unknown)]
69            _ => return Err(unknown_error()),
70        }
71        Ok(())
72    }
73}
74
75#[node_impl]
76impl MacroNode for JSXAttr {
77    fn emit(&mut self, emitter: &mut Macro) -> Result {
78        emit!(self.name);
79
80        if let Some(ref value) = self.value {
81            punct!(emitter, "=");
82            emit!(value);
83        }
84        Ok(())
85    }
86}
87
88#[node_impl]
89impl MacroNode for JSXAttrValue {
90    fn emit(&mut self, emitter: &mut Macro) -> Result {
91        match *self {
92            JSXAttrValue::Lit(ref n) => emit!(n),
93            JSXAttrValue::JSXExprContainer(ref n) => emit!(n),
94            JSXAttrValue::JSXElement(ref n) => emit!(n),
95            JSXAttrValue::JSXFragment(ref n) => emit!(n),
96            #[cfg(swc_ast_unknown)]
97            _ => return Err(unknown_error()),
98        }
99        Ok(())
100    }
101}
102
103#[node_impl]
104impl MacroNode for JSXAttrName {
105    fn emit(&mut self, emitter: &mut Macro) -> Result {
106        match *self {
107            JSXAttrName::Ident(ref n) => emit!(n),
108            JSXAttrName::JSXNamespacedName(ref n) => emit!(n),
109            #[cfg(swc_ast_unknown)]
110            _ => return Err(unknown_error()),
111        }
112        Ok(())
113    }
114}
115
116#[node_impl]
117impl MacroNode for JSXAttrOrSpread {
118    fn emit(&mut self, emitter: &mut Macro) -> Result {
119        match *self {
120            JSXAttrOrSpread::JSXAttr(ref n) => emit!(n),
121            JSXAttrOrSpread::SpreadElement(ref n) => {
122                punct!(emitter, "{");
123                emit!(n);
124                punct!(emitter, "}");
125            }
126            #[cfg(swc_ast_unknown)]
127            _ => return Err(unknown_error()),
128        }
129        Ok(())
130    }
131}
132
133#[node_impl]
134impl MacroNode for JSXElementChild {
135    fn emit(&mut self, emitter: &mut Macro) -> Result {
136        match *self {
137            JSXElementChild::JSXElement(ref n) => emit!(n),
138            JSXElementChild::JSXExprContainer(ref n) => emit!(n),
139            JSXElementChild::JSXFragment(ref n) => emit!(n),
140            JSXElementChild::JSXSpreadChild(ref n) => emit!(n),
141            JSXElementChild::JSXText(ref n) => emit!(n),
142            #[cfg(swc_ast_unknown)]
143            _ => return Err(unknown_error()),
144        }
145        Ok(())
146    }
147}
148
149#[node_impl]
150impl MacroNode for JSXSpreadChild {
151    fn emit(&mut self, emitter: &mut Macro) -> Result {
152        punct!(emitter, "{");
153        punct!(emitter, "...");
154        emit!(self.expr);
155        punct!(emitter, "}");
156        Ok(())
157    }
158}
159
160#[node_impl]
161impl MacroNode for JSXExprContainer {
162    fn emit(&mut self, emitter: &mut Macro) -> Result {
163        punct!(emitter, "{");
164        emitter.emit_trailing_comments_of_pos(self.span.lo + BytePos(1), true, false)?;
165        emit!(self.expr);
166        punct!(emitter, "}");
167        Ok(())
168    }
169}
170
171#[node_impl]
172impl MacroNode for JSXExpr {
173    fn emit(&mut self, emitter: &mut Macro) -> Result {
174        match *self {
175            JSXExpr::Expr(ref n) => emit!(n),
176            JSXExpr::JSXEmptyExpr(ref n) => emit!(n),
177            #[cfg(swc_ast_unknown)]
178            _ => return Err(unknown_error()),
179        }
180        Ok(())
181    }
182}
183
184#[node_impl]
185impl MacroNode for JSXClosingElement {
186    fn emit(&mut self, emitter: &mut Macro) -> Result {
187        punct!(emitter, "</");
188        emit!(self.name);
189        punct!(emitter, ">");
190        Ok(())
191    }
192}
193
194#[node_impl]
195impl MacroNode for JSXFragment {
196    fn emit(&mut self, emitter: &mut Macro) -> Result {
197        emit!(self.opening);
198
199        emitter.emit_list(
200            self.span(),
201            Some(&self.children),
202            ListFormat::JsxElementOrFragmentChildren,
203        )?;
204
205        emit!(self.closing);
206        Ok(())
207    }
208}
209
210#[node_impl]
211impl MacroNode for JSXOpeningFragment {
212    fn emit(&mut self, emitter: &mut Macro) -> Result {
213        punct!(emitter, "<>");
214        Ok(())
215    }
216}
217
218#[node_impl]
219impl MacroNode for JSXClosingFragment {
220    fn emit(&mut self, emitter: &mut Macro) -> Result {
221        punct!(emitter, "</>");
222        Ok(())
223    }
224}
225
226#[node_impl]
227impl MacroNode for JSXNamespacedName {
228    fn emit(&mut self, emitter: &mut Macro) -> Result {
229        emit!(self.ns);
230        punct!(emitter, ":");
231        emit!(self.name);
232        Ok(())
233    }
234}
235
236#[node_impl]
237impl MacroNode for JSXEmptyExpr {
238    fn emit(&mut self, emitter: &mut Macro) -> Result {
239        Ok(())
240    }
241}
242
243#[node_impl]
244impl MacroNode for JSXText {
245    fn emit(&mut self, emitter: &mut Macro) -> Result {
246        emitter.emit_atom(self.span(), &self.raw)?;
247        Ok(())
248    }
249}
250
251#[node_impl]
252impl MacroNode for JSXMemberExpr {
253    fn emit(&mut self, emitter: &mut Macro) -> Result {
254        emit!(self.obj);
255        punct!(emitter, ".");
256        emit!(self.prop);
257        Ok(())
258    }
259}
260
261#[node_impl]
262impl MacroNode for JSXObject {
263    fn emit(&mut self, emitter: &mut Macro) -> Result {
264        match *self {
265            JSXObject::Ident(ref n) => emit!(n),
266            JSXObject::JSXMemberExpr(ref n) => emit!(n),
267            #[cfg(swc_ast_unknown)]
268            _ => return Err(unknown_error()),
269        }
270        Ok(())
271    }
272}