swc_ecma_codegen/text_writer/
semicolon.rs1use swc_common::{BytePos, Span, DUMMY_SP};
2
3use super::{Result, WriteJs};
4
5pub fn omit_trailing_semi<W: WriteJs>(w: W) -> impl WriteJs {
6 OmitTrailingSemi {
7 inner: w,
8 pending_semi: None,
9 }
10}
11
12#[derive(Debug, Clone)]
13struct OmitTrailingSemi<W: WriteJs> {
14 inner: W,
15 pending_semi: Option<Span>,
16}
17
18macro_rules! with_semi {
19 (
20 $fn_name:ident
21 (
22 $(
23 $arg_name:ident
24 :
25 $arg_ty:ty
26 ),*
27 )
28 ) => {
29 fn $fn_name(&mut self, $($arg_name: $arg_ty),* ) -> Result {
30 self.commit_pending_semi()?;
31
32 self.inner.$fn_name( $($arg_name),* )
33 }
34 };
35}
36
37impl<W: WriteJs> WriteJs for OmitTrailingSemi<W> {
38 with_semi!(increase_indent());
39
40 with_semi!(decrease_indent());
41
42 with_semi!(write_space());
43
44 with_semi!(write_comment(s: &str));
45
46 with_semi!(write_keyword(span: Option<Span>, s: &'static str));
47
48 with_semi!(write_operator(span: Option<Span>, s: &str));
49
50 with_semi!(write_param(s: &str));
51
52 with_semi!(write_property(s: &str));
53
54 with_semi!(write_line());
55
56 with_semi!(write_lit(span: Span, s: &str));
57
58 with_semi!(write_str_lit(span: Span, s: &str));
59
60 with_semi!(write_str(s: &str));
61
62 with_semi!(write_symbol(span: Span, s: &str));
63
64 fn write_semi(&mut self, span: Option<Span>) -> Result {
65 self.pending_semi = Some(span.unwrap_or(DUMMY_SP));
66 Ok(())
67 }
68
69 fn write_punct(&mut self, span: Option<Span>, s: &'static str) -> Result {
70 match s {
71 "\"" | "'" | "[" | "!" | "/" | "{" | "(" | "~" | "-" | "+" | "#" | "`" | "*" => {
72 self.commit_pending_semi()?;
73 }
74
75 _ => {
76 self.pending_semi = None;
77 }
78 }
79
80 self.inner.write_punct(span, s)
81 }
82
83 #[inline]
84 fn care_about_srcmap(&self) -> bool {
85 self.inner.care_about_srcmap()
86 }
87
88 #[inline]
89 fn add_srcmap(&mut self, pos: BytePos) -> Result {
90 self.inner.add_srcmap(pos)
91 }
92
93 fn commit_pending_semi(&mut self) -> Result {
94 if let Some(span) = self.pending_semi {
95 self.inner.write_semi(Some(span))?;
96 self.pending_semi = None;
97 }
98 Ok(())
99 }
100
101 #[inline(always)]
102 fn can_ignore_invalid_unicodes(&mut self) -> bool {
103 self.inner.can_ignore_invalid_unicodes()
104 }
105}