swc_ecma_codegen/
object.rs1use swc_common::{Spanned, DUMMY_SP};
2use swc_ecma_ast::*;
3use swc_ecma_codegen_macros::node_impl;
4
5#[cfg(swc_ast_unknown)]
6use crate::unknown_error;
7use crate::{is_empty_comments, ListFormat};
8
9#[node_impl]
10impl MacroNode for ObjectLit {
11 fn emit(&mut self, emitter: &mut Macro) -> Result {
12 emitter.emit_leading_comments_of_span(self.span(), false)?;
13
14 srcmap!(emitter, self, true);
15
16 punct!(emitter, "{");
17
18 let emit_new_line = !emitter.cfg.minify
19 && !(self.props.is_empty() && is_empty_comments(&self.span(), &emitter.comments));
20
21 if emit_new_line {
22 emitter.wr.write_line()?;
23 }
24
25 let mut list_format =
26 ListFormat::ObjectLiteralExpressionProperties | ListFormat::CanSkipTrailingComma;
27
28 if !emit_new_line {
29 list_format -= ListFormat::MultiLine | ListFormat::Indented;
30 }
31
32 emitter.emit_list(self.span(), Some(&self.props), list_format)?;
33
34 if emit_new_line {
35 emitter.wr.write_line()?;
36 }
37
38 srcmap!(emitter, self, false, true);
39 punct!(emitter, "}");
40
41 Ok(())
42 }
43}
44
45#[node_impl]
46impl MacroNode for Prop {
47 fn emit(&mut self, emitter: &mut Macro) -> Result {
48 match self {
49 Prop::Shorthand(ref n) => emit!(n),
50 Prop::KeyValue(ref n) => emit!(n),
51 Prop::Assign(ref n) => emit!(n),
52 Prop::Getter(ref n) => emit!(n),
53 Prop::Setter(ref n) => emit!(n),
54 Prop::Method(ref n) => emit!(n),
55 #[cfg(swc_ast_unknown)]
56 _ => return Err(unknown_error()),
57 }
58
59 Ok(())
60 }
61}
62
63#[node_impl]
64impl MacroNode for KeyValueProp {
65 fn emit(&mut self, emitter: &mut Macro) -> Result {
66 emitter.emit_leading_comments_of_span(self.span(), false)?;
67 let key_span = self.key.span();
68 let value_span = self.value.span();
69 if !key_span.is_dummy() {
70 emitter.wr.add_srcmap(key_span.lo)?;
71 }
72 emit!(self.key);
73 if !key_span.is_dummy() && value_span.is_dummy() {
74 emitter.wr.add_srcmap(key_span.hi)?;
75 }
76 punct!(emitter, ":");
77 formatting_space!(emitter);
78 if key_span.is_dummy() && !value_span.is_dummy() {
79 emitter.wr.add_srcmap(value_span.lo)?;
80 }
81 emit!(self.value);
82
83 Ok(())
84 }
85}
86
87#[node_impl]
88impl MacroNode for AssignProp {
89 fn emit(&mut self, emitter: &mut Macro) -> Result {
90 emitter.emit_leading_comments_of_span(self.span(), false)?;
91
92 srcmap!(emitter, self, true);
93
94 emit!(self.key);
95 punct!(emitter, "=");
96 emit!(self.value);
97
98 Ok(())
99 }
100}
101
102#[node_impl]
103impl MacroNode for GetterProp {
104 fn emit(&mut self, emitter: &mut Macro) -> Result {
105 emitter.emit_leading_comments_of_span(self.span(), false)?;
106
107 srcmap!(emitter, self, true);
108
109 keyword!(emitter, "get");
110
111 let starts_with_alpha_num = match self.key {
112 PropName::Str(_) | PropName::Computed(_) => false,
113 _ => true,
114 };
115 if starts_with_alpha_num {
116 space!(emitter);
117 } else {
118 formatting_space!(emitter);
119 }
120 emit!(self.key);
121 formatting_space!(emitter);
122 punct!(emitter, "(");
123 punct!(emitter, ")");
124 formatting_space!(emitter);
125 emit!(self.body);
126
127 Ok(())
128 }
129}
130
131#[node_impl]
132impl MacroNode for SetterProp {
133 fn emit(&mut self, emitter: &mut Macro) -> Result {
134 emitter.emit_leading_comments_of_span(self.span(), false)?;
135
136 srcmap!(emitter, self, true);
137
138 keyword!(emitter, "set");
139
140 let starts_with_alpha_num = match self.key {
141 PropName::Str(_) | PropName::Computed(_) => false,
142 _ => true,
143 };
144
145 if starts_with_alpha_num {
146 space!(emitter);
147 } else {
148 formatting_space!(emitter);
149 }
150
151 emit!(self.key);
152 formatting_space!(emitter);
153
154 punct!(emitter, "(");
155 if let Some(this) = &self.this_param {
156 emit!(this);
157 punct!(emitter, ",");
158
159 formatting_space!(emitter);
160 }
161
162 emit!(self.param);
163
164 punct!(emitter, ")");
165
166 emit!(self.body);
167
168 Ok(())
169 }
170}
171
172#[node_impl]
173impl MacroNode for MethodProp {
174 fn emit(&mut self, emitter: &mut Macro) -> Result {
175 emitter.emit_leading_comments_of_span(self.span(), false)?;
176
177 srcmap!(emitter, self, true);
178
179 if self.function.is_async {
180 keyword!(emitter, "async");
181 space!(emitter);
182 }
183
184 if self.function.is_generator {
185 punct!(emitter, "*");
186 }
187
188 emit!(self.key);
189 formatting_space!(emitter);
190 emitter.emit_fn_trailing(&self.function)?;
192
193 Ok(())
194 }
195}
196
197#[node_impl]
198impl MacroNode for PropName {
199 fn emit(&mut self, emitter: &mut Macro) -> Result {
200 match self {
201 PropName::Ident(ident) => {
202 emitter.emit_leading_comments_of_span(ident.span, false)?;
204
205 emitter.wr.commit_pending_semi()?;
207
208 srcmap!(emitter, ident, true);
209
210 if emitter.cfg.ascii_only {
211 if emitter.wr.can_ignore_invalid_unicodes() {
212 emitter.wr.write_symbol(
213 DUMMY_SP,
214 &crate::get_ascii_only_ident(&ident.sym, true, emitter.cfg.target),
215 )?;
216 } else {
217 emitter.wr.write_symbol(
218 DUMMY_SP,
219 &crate::get_ascii_only_ident(
220 &crate::handle_invalid_unicodes(&ident.sym),
221 true,
222 emitter.cfg.target,
223 ),
224 )?;
225 }
226 } else {
227 emit!(ident);
228 }
229 }
230 PropName::Str(ref n) => emit!(n),
231 PropName::Num(ref n) => emit!(n),
232 PropName::BigInt(ref n) => emit!(n),
233 PropName::Computed(ref n) => emit!(n),
234 #[cfg(swc_ast_unknown)]
235 _ => return Err(unknown_error()),
236 }
237
238 Ok(())
239 }
240}
241
242#[node_impl]
243impl MacroNode for ComputedPropName {
244 fn emit(&mut self, emitter: &mut Macro) -> Result {
245 srcmap!(emitter, self, true);
246
247 punct!(emitter, "[");
248 emit!(self.expr);
249 punct!(emitter, "]");
250
251 srcmap!(emitter, self, false);
252
253 Ok(())
254 }
255}