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}