swc_ecma_codegen/
jsx.rs

1use swc_common::{SourceMapper, Spanned};
2use swc_ecma_ast::*;
3use swc_ecma_codegen_macros::emitter;
4
5use super::{Emitter, Result};
6use crate::text_writer::WriteJs;
7
8impl<W, S: SourceMapper> Emitter<'_, W, S>
9where
10    W: WriteJs,
11    S: SourceMapperExt,
12{
13    #[emitter]
14    fn emit_jsx_element(&mut self, node: &JSXElement) -> Result {
15        emit!(node.opening);
16        self.emit_list(
17            node.span(),
18            Some(&node.children),
19            ListFormat::JsxElementOrFragmentChildren,
20        )?;
21        if let Some(ref closing) = node.closing {
22            emit!(closing)
23        }
24    }
25
26    #[emitter]
27    fn emit_jsx_opening_element(&mut self, node: &JSXOpeningElement) -> Result {
28        punct!("<");
29        emit!(node.name);
30
31        if let Some(type_args) = &node.type_args {
32            emit!(type_args);
33        }
34
35        if !node.attrs.is_empty() {
36            space!();
37
38            self.emit_list(
39                node.span(),
40                Some(&node.attrs),
41                ListFormat::JsxElementAttributes,
42            )?;
43        }
44
45        if node.self_closing {
46            punct!("/");
47        }
48        punct!(">");
49    }
50
51    #[emitter]
52    fn emit_jsx_element_name(&mut self, node: &JSXElementName) -> Result {
53        match *node {
54            JSXElementName::Ident(ref n) => emit!(n),
55            JSXElementName::JSXMemberExpr(ref n) => emit!(n),
56            JSXElementName::JSXNamespacedName(ref n) => emit!(n),
57        }
58    }
59
60    #[emitter]
61    fn emit_jsx_attr(&mut self, node: &JSXAttr) -> Result {
62        emit!(node.name);
63
64        if let Some(ref value) = node.value {
65            punct!("=");
66
67            emit!(value);
68        }
69    }
70
71    #[emitter]
72    fn emit_jsx_attr_value(&mut self, node: &JSXAttrValue) -> Result {
73        match *node {
74            JSXAttrValue::Lit(ref n) => emit!(n),
75            JSXAttrValue::JSXExprContainer(ref n) => emit!(n),
76            JSXAttrValue::JSXElement(ref n) => emit!(n),
77            JSXAttrValue::JSXFragment(ref n) => emit!(n),
78        }
79    }
80
81    #[emitter]
82    fn emit_jsx_attr_name(&mut self, node: &JSXAttrName) -> Result {
83        match *node {
84            JSXAttrName::Ident(ref n) => emit!(n),
85            JSXAttrName::JSXNamespacedName(ref n) => emit!(n),
86        }
87    }
88
89    #[emitter]
90    fn emit_jsx_attr_or_spread(&mut self, node: &JSXAttrOrSpread) -> Result {
91        match *node {
92            JSXAttrOrSpread::JSXAttr(ref n) => emit!(n),
93            JSXAttrOrSpread::SpreadElement(ref n) => {
94                punct!("{");
95                emit!(n);
96                punct!("}");
97            }
98        }
99    }
100
101    #[emitter]
102    fn emit_jsx_element_child(&mut self, node: &JSXElementChild) -> Result {
103        match *node {
104            JSXElementChild::JSXElement(ref n) => emit!(n),
105            JSXElementChild::JSXExprContainer(ref n) => emit!(n),
106            JSXElementChild::JSXFragment(ref n) => emit!(n),
107            JSXElementChild::JSXSpreadChild(ref n) => emit!(n),
108            JSXElementChild::JSXText(ref n) => emit!(n),
109        }
110    }
111
112    #[emitter]
113    fn emit_jsx_spread_child(&mut self, node: &JSXSpreadChild) -> Result {
114        punct!("{");
115        punct!("...");
116        emit!(node.expr);
117        punct!("}");
118    }
119
120    #[emitter]
121    fn emit_jsx_expr_container(&mut self, node: &JSXExprContainer) -> Result {
122        punct!("{");
123        emit!(node.expr);
124        punct!("}");
125    }
126
127    #[emitter]
128    fn emit_jsx_expr(&mut self, node: &JSXExpr) -> Result {
129        match *node {
130            JSXExpr::Expr(ref n) => emit!(n),
131            JSXExpr::JSXEmptyExpr(ref n) => emit!(n),
132        }
133    }
134
135    #[emitter]
136    fn emit_jsx_closing_element(&mut self, node: &JSXClosingElement) -> Result {
137        punct!("</");
138        emit!(node.name);
139        punct!(">");
140    }
141
142    #[emitter]
143    fn emit_jsx_fragment(&mut self, node: &JSXFragment) -> Result {
144        emit!(node.opening);
145
146        self.emit_list(
147            node.span(),
148            Some(&node.children),
149            ListFormat::JsxElementOrFragmentChildren,
150        )?;
151
152        emit!(node.closing);
153    }
154
155    #[emitter]
156    fn emit_jsx_opening_fragment(&mut self, _: &JSXOpeningFragment) -> Result {
157        punct!("<>")
158    }
159
160    #[emitter]
161    fn emit_jsx_closing_fragment(&mut self, _: &JSXClosingFragment) -> Result {
162        punct!("</>")
163    }
164
165    #[emitter]
166    fn emit_jsx_namespaced_name(&mut self, node: &JSXNamespacedName) -> Result {
167        emit!(node.ns);
168        punct!(":");
169        emit!(node.name);
170    }
171
172    #[emitter]
173    fn emit_jsx_empty_expr(&mut self, _: &JSXEmptyExpr) -> Result {}
174
175    #[emitter]
176    fn emit_jsx_text(&mut self, node: &JSXText) -> Result {
177        self.emit_atom(node.span(), &node.raw)?;
178    }
179
180    #[emitter]
181    fn emit_jsx_member_expr(&mut self, node: &JSXMemberExpr) -> Result {
182        emit!(node.obj);
183        punct!(".");
184        emit!(node.prop);
185    }
186
187    #[emitter]
188    fn emit_jsx_object(&mut self, node: &JSXObject) -> Result {
189        match *node {
190            JSXObject::Ident(ref n) => emit!(n),
191            JSXObject::JSXMemberExpr(ref n) => emit!(n),
192        }
193    }
194}