swc_ecma_lexer/common/lexer/
char.rs

1/// Implemented for `char`.
2pub trait CharExt: Copy {
3    fn to_char(self) -> Option<char>;
4
5    /// Test whether a given character code starts an identifier.
6    ///
7    /// https://tc39.github.io/ecma262/#prod-IdentifierStart
8    #[inline]
9    fn is_ident_start(self) -> bool {
10        let c = match self.to_char() {
11            Some(c) => c,
12            None => return false,
13        };
14        swc_ecma_ast::Ident::is_valid_start(c)
15    }
16
17    /// Test whether a given character is part of an identifier.
18    #[inline]
19    fn is_ident_part(self) -> bool {
20        let c = match self.to_char() {
21            Some(c) => c,
22            None => return false,
23        };
24        swc_ecma_ast::Ident::is_valid_continue(c)
25    }
26
27    /// See https://tc39.github.io/ecma262/#sec-line-terminators
28    #[inline]
29    fn is_line_terminator(self) -> bool {
30        let c = match self.to_char() {
31            Some(c) => c,
32            None => return false,
33        };
34        matches!(c, '\r' | '\n' | '\u{2028}' | '\u{2029}')
35    }
36
37    /// See https://tc39.github.io/ecma262/#sec-literals-string-literals
38    #[inline]
39    fn is_line_break(self) -> bool {
40        let c = match self.to_char() {
41            Some(c) => c,
42            None => return false,
43        };
44        matches!(c, '\r' | '\n')
45    }
46
47    /// See https://tc39.github.io/ecma262/#sec-white-space
48    #[inline]
49    fn is_ws(self) -> bool {
50        let c = match self.to_char() {
51            Some(c) => c,
52            None => return false,
53        };
54        match c {
55            '\u{0009}' | '\u{000b}' | '\u{000c}' | '\u{0020}' | '\u{00a0}' | '\u{feff}' => true,
56            _ => {
57                if self.is_line_terminator() {
58                    // NOTE: Line terminator is not whitespace.
59                    false
60                } else {
61                    c.is_whitespace()
62                }
63            }
64        }
65    }
66}
67
68impl CharExt for char {
69    #[inline(always)]
70    fn to_char(self) -> Option<char> {
71        Some(self)
72    }
73}