diff --git a/crates/oxc_parser/src/cursor.rs b/crates/oxc_parser/src/cursor.rs index 12c9026e5..4babc53f5 100644 --- a/crates/oxc_parser/src/cursor.rs +++ b/crates/oxc_parser/src/cursor.rs @@ -29,7 +29,7 @@ impl<'a> Parser<'a> { /// Get current token #[must_use] - pub fn cur_token(&self) -> &Token { + pub fn cur_token(&self) -> &Token<'a> { &self.token } diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 37de2c5dd..87051e591 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -301,11 +301,13 @@ impl<'a> Parser<'a> { Kind::RegExp => self.cur_token().value.as_regex(), _ => return self.unexpected(), }; + let pattern = Atom::from(r.pattern); + let flags = r.flags; self.bump_any(); Ok(RegExpLiteral { span: self.end_span(span), value: EmptyObject {}, - regex: RegExp { pattern: r.pattern, flags: r.flags }, + regex: RegExp { pattern, flags }, }) } diff --git a/crates/oxc_parser/src/lexer/mod.rs b/crates/oxc_parser/src/lexer/mod.rs index d6fc0788e..3e8000657 100644 --- a/crates/oxc_parser/src/lexer/mod.rs +++ b/crates/oxc_parser/src/lexer/mod.rs @@ -16,7 +16,7 @@ mod trivia_builder; use std::{collections::VecDeque, str::Chars}; use oxc_allocator::{Allocator, String}; -use oxc_ast::{ast::RegExpFlags, Atom, SourceType, Span}; +use oxc_ast::{ast::RegExpFlags, SourceType, Span}; use oxc_diagnostics::{Diagnostics, Error}; use simd::{SkipMultilineComment, SkipWhitespace}; pub use token::{RegExp, Token, TokenValue}; @@ -197,7 +197,7 @@ impl<'a> Lexer<'a> { Kind::SlashEq => 2, _ => unreachable!(), }; - let kind = self.read_regex(kind); + let kind = self.read_regex(); self.lookahead.clear(); self.finish_next(kind) } @@ -986,12 +986,8 @@ impl<'a> Lexer<'a> { } /// 12.8.5 Regular Expression Literals - fn read_regex(&mut self, kind: Kind) -> Kind { - let start = self.current.chars.as_str(); - let mut pattern = String::new_in(self.allocator); - if kind == Kind::SlashEq { - pattern.push('='); - } + fn read_regex(&mut self) -> Kind { + let start = self.current.token.start + 1; // +1 to exclude `/` let mut in_escape = false; let mut in_character_class = false; loop { @@ -1020,7 +1016,8 @@ impl<'a> Lexer<'a> { } } - pattern.push_str(&start[..start.len() - self.current.chars.as_str().len() - 1]); + let end = self.offset() - 1; // -1 to exclude `/` + let pattern = &self.source[start as usize..end as usize]; let mut flags = RegExpFlags::empty(); @@ -1051,8 +1048,7 @@ impl<'a> Lexer<'a> { flags |= flag; } - self.current.token.value = - TokenValue::RegExp(RegExp { pattern: Atom::from(pattern.as_str()), flags }); + self.current.token.value = TokenValue::RegExp(RegExp { pattern, flags }); Kind::RegExp } diff --git a/crates/oxc_parser/src/lexer/token.rs b/crates/oxc_parser/src/lexer/token.rs index 982742ee8..6a0e94446 100644 --- a/crates/oxc_parser/src/lexer/token.rs +++ b/crates/oxc_parser/src/lexer/token.rs @@ -1,7 +1,7 @@ //! Token use num_bigint::BigUint; -use oxc_ast::{ast::RegExpFlags, Atom, Span}; +use oxc_ast::{ast::RegExpFlags, Span}; use super::kind::Kind; @@ -29,7 +29,7 @@ pub struct Token<'a> { #[test] fn no_bloat_token() { use std::mem::size_of; - assert_eq!(size_of::(), 56); + assert_eq!(size_of::(), 48); } impl<'a> Token<'a> { @@ -45,12 +45,12 @@ pub enum TokenValue<'a> { Number(f64), BigInt(BigUint), String(&'a str), - RegExp(RegExp), + RegExp(RegExp<'a>), } #[derive(Debug, Clone, PartialEq, Eq)] -pub struct RegExp { - pub pattern: Atom, +pub struct RegExp<'a> { + pub pattern: &'a str, pub flags: RegExpFlags, } @@ -78,9 +78,9 @@ impl<'a> TokenValue<'a> { } #[must_use] - pub fn as_regex(&self) -> RegExp { + pub fn as_regex(&self) -> &RegExp<'a> { match self { - Self::RegExp(regex) => regex.clone(), + Self::RegExp(regex) => regex, _ => panic!("expected regex!"), } }