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