Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/oxc_parser/src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ impl<'a> ParserImpl<'a> {
}

/// Tell lexer to read a regex
pub(crate) fn read_regex(&mut self) -> (u32, RegExpFlags) {
let (token, pattern_end, flags) = self.lexer.next_regex(self.cur_kind());
pub(crate) fn read_regex(&mut self) -> Result<(u32, RegExpFlags)> {
let (token, pattern_end, flags) = self.lexer.next_regex(self.cur_kind())?;
self.token = token;
(pattern_end, flags)
Ok((pattern_end, flags))
}

/// Tell lexer to read a template substitution tail
Expand Down
15 changes: 7 additions & 8 deletions crates/oxc_parser/src/js/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,9 @@ impl<'a> ParserImpl<'a> {
}
}
Kind::LParen => self.parse_parenthesized_expression(span),
Kind::Slash | Kind::SlashEq => {
let literal = self.parse_literal_regexp();
Ok(self.ast.expression_from_reg_exp_literal(literal))
}
Kind::Slash | Kind::SlashEq => self
.parse_literal_regexp()
.map(|literal| self.ast.expression_from_reg_exp_literal(literal)),
// JSXElement, JSXFragment
Kind::LAngle if self.source_type.is_jsx() => self.parse_jsx_expression(),
_ => self.parse_identifier_expression(),
Expand Down Expand Up @@ -336,11 +335,11 @@ impl<'a> ParserImpl<'a> {
Ok(self.ast.big_int_literal(self.end_span(span), raw, base))
}

pub(crate) fn parse_literal_regexp(&mut self) -> RegExpLiteral<'a> {
pub(crate) fn parse_literal_regexp(&mut self) -> Result<RegExpLiteral<'a>> {
let span = self.start_span();

// split out pattern
let (pattern_end, flags) = self.read_regex();
let (pattern_end, flags) = self.read_regex()?;
let pattern_start = self.cur_token().start + 1; // +1 to exclude `/`
let pattern = &self.source_text[pattern_start as usize..pattern_end as usize];
self.bump_any();
Expand All @@ -350,11 +349,11 @@ impl<'a> ParserImpl<'a> {
.parse_regular_expression
.then(|| self.parse_regex_pattern(pattern_start, pattern, flags));

self.ast.reg_exp_literal(
Ok(self.ast.reg_exp_literal(
self.end_span(span),
EmptyObject,
RegExp { pattern: self.ast.atom(pattern), flags },
)
))
}

fn parse_regex_pattern(
Expand Down
20 changes: 9 additions & 11 deletions crates/oxc_parser/src/lexer/regex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use oxc_syntax::identifier::is_line_terminator;

use super::{Kind, Lexer, RegExpFlags, Token};
use crate::diagnostics;
use oxc_diagnostics::Result;

impl<'a> Lexer<'a> {
/// Re-tokenize the current `/` or `/=` and return `RegExp`
Expand All @@ -10,34 +11,31 @@ impl<'a> Lexer<'a> {
/// where a `RegularExpressionLiteral` is permitted
/// Which means the parser needs to re-tokenize on `PrimaryExpression`,
/// `RegularExpressionLiteral` only appear on the right hand side of `PrimaryExpression`
pub(crate) fn next_regex(&mut self, kind: Kind) -> (Token, u32, RegExpFlags) {
pub(crate) fn next_regex(&mut self, kind: Kind) -> Result<(Token, u32, RegExpFlags)> {
self.token.start = self.offset()
- match kind {
Kind::Slash => 1,
Kind::SlashEq => 2,
_ => unreachable!(),
};
let (pattern_end, flags) = self.read_regex();
let (pattern_end, flags) = self.read_regex()?;
self.lookahead.clear();
let token = self.finish_next(Kind::RegExp);
(token, pattern_end, flags)
Ok((token, pattern_end, flags))
}

/// 12.9.5 Regular Expression Literals
fn read_regex(&mut self) -> (u32, RegExpFlags) {
fn read_regex(&mut self) -> Result<(u32, RegExpFlags)> {
let mut in_escape = false;
let mut in_character_class = false;
loop {
match self.next_char() {
None => {
self.error(diagnostics::unterminated_reg_exp(self.unterminated_range()));
return (self.offset(), RegExpFlags::empty());
return Err(diagnostics::unterminated_reg_exp(self.unterminated_range()));
// return (self.offset(), RegExpFlags::empty());
}
Some(c) if is_line_terminator(c) => {
self.error(diagnostics::unterminated_reg_exp(self.unterminated_range()));
#[allow(clippy::cast_possible_truncation)]
let pattern_end = self.offset() - c.len_utf8() as u32;
return (pattern_end, RegExpFlags::empty());
return Err(diagnostics::unterminated_reg_exp(self.unterminated_range()));
}
Some(c) => {
if in_escape {
Expand Down Expand Up @@ -79,6 +77,6 @@ impl<'a> Lexer<'a> {
flags |= flag;
}

(pattern_end, flags)
Ok((pattern_end, flags))
}
}
41 changes: 0 additions & 41 deletions tasks/coverage/parser_babel.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1308,12 +1308,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/380/input.js:1:9]
1 │ var x = /
· ──
2 │ /
╰────

× Unexpected token
╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/380/input.js:2:2]
1 │ var x = /
2 │ /
╰────

Expand Down Expand Up @@ -1696,19 +1690,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/441/input.js:1:1]
1 │ /a\
· ────
2 │ /
╰────

× Invalid regular expression: Invalid escape
╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/441/input.js:1:3]
1 │ /a\
· ─
2 │ /
╰────

× Unexpected token
╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/441/input.js:2:2]
1 │ /a\
2 │ /
╰────

Expand Down Expand Up @@ -8218,11 +8199,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
2 │ /
╰────

× Unexpected token
╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0040/input.js:3:1]
2 │ /
╰────

× Invalid Unicode escape sequence
╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0041/input.js:1:17]
1 │ var x = /[a-z]/\ux
Expand Down Expand Up @@ -8397,11 +8373,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
2 │ /
╰────

× Unexpected token
╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0062/input.js:3:1]
2 │ /
╰────

× Unterminated string
╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0063/input.js:1:9]
1 │ var x = "
Expand Down Expand Up @@ -8942,18 +8913,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
2 │ /
╰────

× Invalid regular expression: Invalid escape
╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0157/input.js:1:3]
1 │ /a\
· ─
2 │ /
╰────

× Unexpected token
╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0157/input.js:3:1]
2 │ /
╰────

× Unexpected token
╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0158/input.js:3:1]
2 │
Expand Down
Loading