diff --git a/crates/oxc_parser/src/lexer/mod.rs b/crates/oxc_parser/src/lexer/mod.rs index 0dd8b4240..3b8a0a713 100644 --- a/crates/oxc_parser/src/lexer/mod.rs +++ b/crates/oxc_parser/src/lexer/mod.rs @@ -20,7 +20,7 @@ use oxc_span::{SourceType, Span}; use oxc_syntax::{ identifier::{ is_identifier_part, is_identifier_start_all, is_irregular_line_terminator, - is_irregular_whitespace, is_line_terminator, CR, EOF, FF, LF, LS, PS, TAB, VT, + is_irregular_whitespace, is_line_terminator, CR, FF, LF, LS, PS, TAB, VT, }, unicode_id_start::is_id_start_unicode, }; @@ -84,7 +84,7 @@ impl<'a> Lexer<'a> { source_type, current, errors: vec![], - lookahead: VecDeque::with_capacity(4), + lookahead: VecDeque::with_capacity(4), // 4 is the maximum lookahead for TypeScript context: LexerContext::Regular, trivia_builder: TriviaBuilder::default(), } @@ -254,21 +254,22 @@ impl<'a> Lexer<'a> { /// Peek the next char without advancing the position #[inline] - fn peek(&self) -> char { - self.current.chars.clone().next().unwrap_or(EOF) + fn peek(&self) -> Option { + self.current.chars.clone().next() } /// Peek the next next char without advancing the position - fn peek2(&self) -> char { + #[inline] + fn peek2(&self) -> Option { let mut chars = self.current.chars.clone(); chars.next(); - chars.next().unwrap_or(EOF) + chars.next() } /// Peek the next character, and advance the current position if it matches #[inline] fn next_eq(&mut self, c: char) -> bool { - let matched = self.peek() == c; + let matched = self.peek() == Some(c); if matched { self.current.chars.next(); } @@ -282,11 +283,10 @@ impl<'a> Lexer<'a> { /// Return `IllegalCharacter` Error or `UnexpectedEnd` if EOF fn unexpected_err(&mut self) { - let c = self.peek(); - if c == EOF { - self.error(diagnostics::UnexpectedEnd(self.current_offset())); - } else { - self.error(diagnostics::InvalidCharacter(c, self.current_offset())); + let offset = self.current_offset(); + match self.peek() { + Some(c) => self.error(diagnostics::InvalidCharacter(c, offset)), + None => self.error(diagnostics::UnexpectedEnd(offset)), } } @@ -419,8 +419,7 @@ impl<'a> Lexer<'a> { /// Section 12.6.1 Identifier Names fn identifier_tail(&mut self, mut builder: AutoCow<'a>) -> (bool, &'a str) { // ident tail - loop { - let c = self.peek(); + while let Some(c) = self.peek() { if !is_identifier_part(c) { if c == '\\' { self.current.chars.next(); @@ -453,12 +452,12 @@ impl<'a> Lexer<'a> { /// Section 12.7 Punctuators fn read_dot(&mut self, builder: &mut AutoCow<'a>) -> Kind { - if self.peek() == '.' && self.peek2() == '.' { + if self.peek() == Some('.') && self.peek2() == Some('.') { self.current.chars.next(); self.current.chars.next(); return Kind::Dot3; } - if self.peek().is_ascii_digit() { + if self.peek().is_some_and(|c| c.is_ascii_digit()) { builder.push_matching('.'); self.decimal_literal_after_decimal_point(builder) } else { @@ -476,7 +475,7 @@ impl<'a> Lexer<'a> { } } else if self.next_eq('=') { Some(Kind::LtEq) - } else if self.peek() == '!' + } else if self.peek() == Some('!') // SingleLineHTMLOpenComment `