(&mut self, offset: u32)
| 898 | impl<'a> Lexer<'a> { |
| 899 | #[must_use] |
| 900 | pub(crate) fn read_next_token(&mut self, offset: u32) -> Token { |
| 901 | if self.source.len() as u32 == offset { |
| 902 | return Token::EOF; |
| 903 | } |
| 904 | let bytes = self.source.as_bytes(); |
| 905 | let mut cursor = ByteCursor::new(&bytes[offset as usize..]); |
| 906 | let b = cursor.peek_byte(0); |
| 907 | // fast path for single character tokens (ASCII only) |
| 908 | if b < 128 { |
| 909 | let token = SINGLE_CHAR_TOKENS[b as usize]; |
| 910 | if token != Token::EOF { |
| 911 | return token; |
| 912 | } |
| 913 | // fast path for identifiers |
| 914 | if is_ident_ascii_start(b as char) { |
| 915 | if matches!(b, b'U' | b'u') |
| 916 | && self.features.intersects(Feature::UnicodeRange) |
| 917 | && cursor.would_start_unicode_range() |
| 918 | { |
| 919 | return cursor.consume_unicode_range_token(); |
| 920 | } |
| 921 | return cursor.consume_ident_like_token(self.atoms); |
| 922 | } |
| 923 | } |
| 924 | let c = cursor.peek_char(); |
| 925 | match c { |
| 926 | '\0' => { |
| 927 | if !cursor.is_last() { |
| 928 | let (_, c2, c3) = cursor.peek3(); |
| 929 | if is_ident_start_sequence(REPLACEMENT_CHARACTER, c2, c3) { |
| 930 | return cursor.consume_ident_like_token(self.atoms); |
| 931 | } |
| 932 | } |
| 933 | if cursor.next_char().is_some() { Token::REPLACEMENT_CHARACTER } else { Token::EOF } |
| 934 | } |
| 935 | c if is_whitespace(c) && !self.features.contains(Feature::SeparateWhitespace) => { |
| 936 | let (len, style) = cursor.consume_whitespace(); |
| 937 | Token::new_whitespace(style, len) |
| 938 | } |
| 939 | // Whitespace Range |
| 940 | TAB => Token::new_whitespace(Whitespace::Tab, cursor.consume_same(b'\t')), |
| 941 | SPACE => Token::new_whitespace(Whitespace::Space, cursor.consume_same(b' ')), |
| 942 | LF | CR | FF => { |
| 943 | let mut len: u32 = 0; |
| 944 | loop { |
| 945 | let nb = cursor.peek_byte(0); |
| 946 | if !matches!(nb, b'\n' | b'\r' | 0x0C) { |
| 947 | break; |
| 948 | } |
| 949 | cursor.pos += 1; |
| 950 | len += 1; |
| 951 | } |
| 952 | Token::new_whitespace(Whitespace::Newline, len) |
| 953 | } |
| 954 | // Quote Range |
| 955 | c if is_quote(c) => cursor.consume_string_token(), |
| 956 | // Digit Range |
| 957 | c if c.is_ascii_digit() => cursor.consume_numeric_token(self.atoms), |
no test coverage detected