swc_ecma_codegen/text_writer/
semicolon.rs

1use 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}