1use swc_common::{LineCol, Span};
2
3pub use self::{basic_impl::JsWriter, semicolon::omit_trailing_semi};
4use super::*;
5
6mod basic_impl;
7mod semicolon;
8
9pub type Symbol = Str;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum ScopeKind {
14 Global,
15 Module,
16 Function,
17 Block,
18 Catch,
19}
20
21impl ScopeKind {
22 #[inline]
23 pub const fn is_hoist_target(self) -> bool {
24 matches!(self, Self::Global | Self::Module | Self::Function)
25 }
26
27 #[inline]
28 pub const fn as_str(self) -> &'static str {
29 match self {
30 ScopeKind::Global => "global",
31 ScopeKind::Module => "module",
32 ScopeKind::Function => "function",
33 ScopeKind::Block => "block",
34 ScopeKind::Catch => "catch",
35 }
36 }
37}
38
39#[derive(Debug, Clone, Copy, PartialEq, Eq)]
40pub enum BindingStorage {
41 Hoisted,
42 Lexical,
43}
44
45#[derive(Debug, Clone, PartialEq, Eq)]
46pub struct ScopeBindingRecord {
47 pub name: String,
48 pub expression: Option<String>,
49 pub storage: BindingStorage,
50}
51
52#[derive(Debug, Clone, PartialEq, Eq)]
53pub struct ScopeRecord {
54 pub parent: Option<u32>,
55 pub generated_start: LineCol,
56 pub generated_end: Option<LineCol>,
57 pub original_span: Option<Span>,
58 pub kind: ScopeKind,
59 pub is_stack_frame: bool,
60 pub is_hidden: bool,
61 pub name: Option<String>,
62 pub bindings: Vec<ScopeBindingRecord>,
63}
64
65pub trait WriteJs {
69 fn increase_indent(&mut self) -> Result;
70 fn decrease_indent(&mut self) -> Result;
71
72 fn write_semi(&mut self, span: Option<Span>) -> Result;
74
75 fn write_space(&mut self) -> Result;
76 fn write_keyword(&mut self, span: Option<Span>, s: &'static str) -> Result;
77 fn write_operator(&mut self, span: Option<Span>, s: &str) -> Result;
78 fn write_param(&mut self, s: &str) -> Result;
79 fn write_property(&mut self, s: &str) -> Result;
80
81 fn write_line(&mut self) -> Result;
82
83 fn write_lit(&mut self, span: Span, s: &str) -> Result;
84 fn write_comment(&mut self, s: &str) -> Result;
85
86 fn write_str_lit(&mut self, span: Span, s: &str) -> Result;
87 fn write_str(&mut self, s: &str) -> Result;
88
89 fn write_symbol(&mut self, span: Span, s: &str) -> Result;
90
91 fn write_punct(
97 &mut self,
98 span: Option<Span>,
99 s: &'static str,
100 commit_pending_semi: bool,
101 ) -> Result;
102
103 fn care_about_srcmap(&self) -> bool;
104
105 fn add_srcmap(&mut self, pos: BytePos) -> Result;
106
107 fn commit_pending_semi(&mut self) -> Result;
108
109 fn can_ignore_invalid_unicodes(&mut self) -> bool {
114 false
115 }
116
117 fn has_scope_tracking(&self) -> bool {
122 false
123 }
124
125 fn start_scope(
129 &mut self,
130 _name: Option<&str>,
131 _kind: ScopeKind,
132 _is_stack_frame: bool,
133 _is_hidden: bool,
134 _original_span: Option<Span>,
135 ) -> Result {
136 Ok(())
137 }
138
139 fn end_scope(&mut self) -> Result {
143 Ok(())
144 }
145
146 fn add_scope_variable(
150 &mut self,
151 _name: &str,
152 _expression: Option<&str>,
153 _storage: BindingStorage,
154 ) -> Result {
155 Ok(())
156 }
157}
158
159impl<W> WriteJs for Box<W>
160where
161 W: ?Sized + WriteJs,
162{
163 #[inline]
164 fn increase_indent(&mut self) -> Result {
165 (**self).increase_indent()
166 }
167
168 #[inline]
169 fn decrease_indent(&mut self) -> Result {
170 (**self).decrease_indent()
171 }
172
173 #[inline]
174 fn write_semi(&mut self, span: Option<Span>) -> Result {
175 (**self).write_semi(span)
176 }
177
178 #[inline]
179 fn write_space(&mut self) -> Result {
180 (**self).write_space()
181 }
182
183 #[inline]
184 fn write_keyword(&mut self, span: Option<Span>, s: &'static str) -> Result {
185 (**self).write_keyword(span, s)
186 }
187
188 #[inline]
189 fn write_operator(&mut self, span: Option<Span>, s: &str) -> Result {
190 (**self).write_operator(span, s)
191 }
192
193 #[inline]
194 fn write_param(&mut self, s: &str) -> Result {
195 (**self).write_param(s)
196 }
197
198 #[inline]
199 fn write_property(&mut self, s: &str) -> Result {
200 (**self).write_property(s)
201 }
202
203 #[inline]
204 fn write_line(&mut self) -> Result {
205 (**self).write_line()
206 }
207
208 #[inline]
209 fn write_lit(&mut self, span: Span, s: &str) -> Result {
210 (**self).write_lit(span, s)
211 }
212
213 #[inline]
214 fn write_comment(&mut self, s: &str) -> Result {
215 (**self).write_comment(s)
216 }
217
218 #[inline]
219 fn write_str_lit(&mut self, span: Span, s: &str) -> Result {
220 (**self).write_str_lit(span, s)
221 }
222
223 #[inline]
224 fn write_str(&mut self, s: &str) -> Result {
225 (**self).write_str(s)
226 }
227
228 #[inline]
229 fn write_symbol(&mut self, span: Span, s: &str) -> Result {
230 (**self).write_symbol(span, s)
231 }
232
233 #[inline]
234 fn write_punct(
235 &mut self,
236 span: Option<Span>,
237 s: &'static str,
238 commit_pending_semi: bool,
239 ) -> Result {
240 (**self).write_punct(span, s, commit_pending_semi)
241 }
242
243 #[inline]
244 fn care_about_srcmap(&self) -> bool {
245 (**self).care_about_srcmap()
246 }
247
248 #[inline]
249 fn add_srcmap(&mut self, pos: BytePos) -> Result {
250 (**self).add_srcmap(pos)
251 }
252
253 fn commit_pending_semi(&mut self) -> Result {
254 (**self).commit_pending_semi()
255 }
256
257 #[inline(always)]
258 fn can_ignore_invalid_unicodes(&mut self) -> bool {
259 (**self).can_ignore_invalid_unicodes()
260 }
261
262 #[inline(always)]
263 fn has_scope_tracking(&self) -> bool {
264 (**self).has_scope_tracking()
265 }
266
267 #[inline]
268 fn start_scope(
269 &mut self,
270 name: Option<&str>,
271 kind: ScopeKind,
272 is_stack_frame: bool,
273 is_hidden: bool,
274 original_span: Option<Span>,
275 ) -> Result {
276 (**self).start_scope(name, kind, is_stack_frame, is_hidden, original_span)
277 }
278
279 #[inline]
280 fn end_scope(&mut self) -> Result {
281 (**self).end_scope()
282 }
283
284 #[inline]
285 fn add_scope_variable(
286 &mut self,
287 name: &str,
288 expression: Option<&str>,
289 storage: BindingStorage,
290 ) -> Result {
291 (**self).add_scope_variable(name, expression, storage)
292 }
293}
294
295impl<W> WriteJs for &'_ mut W
296where
297 W: ?Sized + WriteJs,
298{
299 #[inline]
300 fn increase_indent(&mut self) -> Result {
301 (**self).increase_indent()
302 }
303
304 #[inline]
305 fn decrease_indent(&mut self) -> Result {
306 (**self).decrease_indent()
307 }
308
309 #[inline]
310 fn write_semi(&mut self, span: Option<Span>) -> Result {
311 (**self).write_semi(span)
312 }
313
314 #[inline]
315 fn write_space(&mut self) -> Result {
316 (**self).write_space()
317 }
318
319 #[inline]
320 fn write_keyword(&mut self, span: Option<Span>, s: &'static str) -> Result {
321 (**self).write_keyword(span, s)
322 }
323
324 #[inline]
325 fn write_operator(&mut self, span: Option<Span>, s: &str) -> Result {
326 (**self).write_operator(span, s)
327 }
328
329 #[inline]
330 fn write_param(&mut self, s: &str) -> Result {
331 (**self).write_param(s)
332 }
333
334 #[inline]
335 fn write_property(&mut self, s: &str) -> Result {
336 (**self).write_property(s)
337 }
338
339 #[inline]
340 fn write_line(&mut self) -> Result {
341 (**self).write_line()
342 }
343
344 #[inline]
345 fn write_lit(&mut self, span: Span, s: &str) -> Result {
346 (**self).write_lit(span, s)
347 }
348
349 #[inline]
350 fn write_comment(&mut self, s: &str) -> Result {
351 (**self).write_comment(s)
352 }
353
354 #[inline]
355 fn write_str_lit(&mut self, span: Span, s: &str) -> Result {
356 (**self).write_str_lit(span, s)
357 }
358
359 #[inline]
360 fn write_str(&mut self, s: &str) -> Result {
361 (**self).write_str(s)
362 }
363
364 #[inline]
365 fn write_symbol(&mut self, span: Span, s: &str) -> Result {
366 (**self).write_symbol(span, s)
367 }
368
369 #[inline]
370 fn write_punct(
371 &mut self,
372 span: Option<Span>,
373 s: &'static str,
374 commit_pending_semi: bool,
375 ) -> Result {
376 (**self).write_punct(span, s, commit_pending_semi)
377 }
378
379 #[inline]
380 fn care_about_srcmap(&self) -> bool {
381 (**self).care_about_srcmap()
382 }
383
384 #[inline]
385 fn add_srcmap(&mut self, pos: BytePos) -> Result {
386 (**self).add_srcmap(pos)
387 }
388
389 #[inline(always)]
390 fn commit_pending_semi(&mut self) -> Result {
391 (**self).commit_pending_semi()
392 }
393
394 #[inline(always)]
395 fn can_ignore_invalid_unicodes(&mut self) -> bool {
396 (**self).can_ignore_invalid_unicodes()
397 }
398
399 #[inline(always)]
400 fn has_scope_tracking(&self) -> bool {
401 (**self).has_scope_tracking()
402 }
403
404 #[inline]
405 fn start_scope(
406 &mut self,
407 name: Option<&str>,
408 kind: ScopeKind,
409 is_stack_frame: bool,
410 is_hidden: bool,
411 original_span: Option<Span>,
412 ) -> Result {
413 (**self).start_scope(name, kind, is_stack_frame, is_hidden, original_span)
414 }
415
416 #[inline]
417 fn end_scope(&mut self) -> Result {
418 (**self).end_scope()
419 }
420
421 #[inline]
422 fn add_scope_variable(
423 &mut self,
424 name: &str,
425 expression: Option<&str>,
426 storage: BindingStorage,
427 ) -> Result {
428 (**self).add_scope_variable(name, expression, storage)
429 }
430}