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}