diff --git a/crates/oxc_parser/src/cursor.rs b/crates/oxc_parser/src/cursor.rs index 6152a33cca8bd..bbe8c46c744dd 100644 --- a/crates/oxc_parser/src/cursor.rs +++ b/crates/oxc_parser/src/cursor.rs @@ -297,15 +297,17 @@ impl<'a> ParserImpl<'a> { pub(crate) fn try_parse( &mut self, func: impl FnOnce(&mut ParserImpl<'a>) -> Result, - ) -> Result { + ) -> Option { let checkpoint = self.checkpoint(); let ctx = self.ctx; let result = func(self); - if result.is_err() { + if let Ok(result) = result { + Some(result) + } else { self.ctx = ctx; self.rewind(checkpoint); + None } - result } pub(crate) fn lookahead(&mut self, predicate: impl Fn(&mut ParserImpl<'a>) -> U) -> U { diff --git a/crates/oxc_parser/src/js/arrow.rs b/crates/oxc_parser/src/js/arrow.rs index 66db265cc1107..b0c44a1e7eaf2 100644 --- a/crates/oxc_parser/src/js/arrow.rs +++ b/crates/oxc_parser/src/js/arrow.rs @@ -328,7 +328,7 @@ impl<'a> ParserImpl<'a> { if self.state.not_parenthesized_arrow.contains(&pos) { return Ok(None); } - if let Ok((type_parameters, params, return_type, r#async, span)) = + if let Some((type_parameters, params, return_type, r#async, span)) = self.try_parse(ParserImpl::parse_parenthesized_arrow_function_head) { return self diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 08d74d4c786d1..a638fc08422bd 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -164,7 +164,7 @@ impl<'a> ParserImpl<'a> { return self.parse_function_expression(span, r#async); } - match &self.cur_kind() { + match self.cur_kind() { Kind::Ident => self.parse_identifier_expression(), // fast path, keywords are checked at the end // Literal, RegularExpressionLiteral kind if kind.is_literal() => self.parse_literal_expression(), @@ -530,8 +530,8 @@ impl<'a> ParserImpl<'a> { in_optional_chain: &mut bool, ) -> Result> { let span = self.start_span(); - self.parse_primary_expression() - .and_then(|lhs| self.parse_member_expression_rest(span, lhs, in_optional_chain)) + let lhs = self.parse_primary_expression()?; + self.parse_member_expression_rest(span, lhs, in_optional_chain) } /// Section 13.3 Super Call @@ -601,7 +601,7 @@ impl<'a> ParserImpl<'a> { self.parse_tagged_template(lhs_span, expr, *in_optional_chain, type_parameters)? } Kind::LAngle | Kind::ShiftLeft => { - if let Ok(Some(arguments)) = + if let Some(Some(arguments)) = self.try_parse(Self::parse_type_arguments_in_expression) { lhs = self.ast.ts_instantiation_expression( @@ -713,7 +713,7 @@ impl<'a> ParserImpl<'a> { *in_optional_chain = if optional_call { true } else { *in_optional_chain }; if optional_call { - if let Ok(Some(args)) = self.try_parse(Self::parse_type_arguments_in_expression) { + if let Some(Some(args)) = self.try_parse(Self::parse_type_arguments_in_expression) { type_arguments = Some(args); } if self.cur_kind().is_template_start_of_tagged_template() { diff --git a/crates/oxc_parser/src/lib.rs b/crates/oxc_parser/src/lib.rs index ee959c463b218..2fba591e8913e 100644 --- a/crates/oxc_parser/src/lib.rs +++ b/crates/oxc_parser/src/lib.rs @@ -417,6 +417,10 @@ impl<'a> ParserImpl<'a> { self.errors.push(error); } + fn errors_count(&self) -> usize { + self.errors.len() + self.lexer.errors.len() + } + fn ts_enabled(&self) -> bool { self.source_type.is_typescript() } diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index a8bf6b7bae523..348e332d3e5a5 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -129,10 +129,11 @@ impl<'a> ParserImpl<'a> { self.bump_any(); return true; } - if matches!(self.cur_kind(), Kind::LBrack | Kind::LCurly) - && self.parse_binding_pattern_kind().is_ok() - { - return true; + if matches!(self.cur_kind(), Kind::LBrack | Kind::LCurly) { + let errors_count = self.errors_count(); + if self.parse_binding_pattern_kind().is_ok() && errors_count == self.errors_count() { + return true; + } } false } @@ -342,7 +343,7 @@ impl<'a> ParserImpl<'a> { | Kind::Undefined | Kind::Never | Kind::Object => { - if let Ok(Some(ty)) = self.try_parse(Self::parse_keyword_and_no_dot) { + if let Some(ty) = self.try_parse(Self::parse_keyword_and_no_dot) { Ok(ty) } else { self.parse_type_reference() @@ -421,62 +422,62 @@ impl<'a> ParserImpl<'a> { } } - fn parse_keyword_and_no_dot(&mut self) -> Result>> { + fn parse_keyword_and_no_dot(&mut self) -> Result> { let span = self.start_span(); let ty = match self.cur_kind() { Kind::Any => { self.bump_any(); - Some(self.ast.ts_any_keyword(self.end_span(span))) + self.ast.ts_any_keyword(self.end_span(span)) } Kind::BigInt => { self.bump_any(); - Some(self.ast.ts_bigint_keyword(self.end_span(span))) + self.ast.ts_bigint_keyword(self.end_span(span)) } Kind::Boolean => { self.bump_any(); - Some(self.ast.ts_boolean_keyword(self.end_span(span))) + self.ast.ts_boolean_keyword(self.end_span(span)) } Kind::Intrinsic => { self.bump_any(); - Some(self.ast.ts_intrinsic_keyword(self.end_span(span))) + self.ast.ts_intrinsic_keyword(self.end_span(span)) } Kind::Never => { self.bump_any(); - Some(self.ast.ts_never_keyword(self.end_span(span))) + self.ast.ts_never_keyword(self.end_span(span)) } Kind::Null => { self.bump_any(); - Some(self.ast.ts_null_keyword(self.end_span(span))) + self.ast.ts_null_keyword(self.end_span(span)) } Kind::Number => { self.bump_any(); - Some(self.ast.ts_number_keyword(self.end_span(span))) + self.ast.ts_number_keyword(self.end_span(span)) } Kind::Object => { self.bump_any(); - Some(self.ast.ts_object_keyword(self.end_span(span))) + self.ast.ts_object_keyword(self.end_span(span)) } Kind::String => { self.bump_any(); - Some(self.ast.ts_string_keyword(self.end_span(span))) + self.ast.ts_string_keyword(self.end_span(span)) } Kind::Symbol => { self.bump_any(); - Some(self.ast.ts_symbol_keyword(self.end_span(span))) + self.ast.ts_symbol_keyword(self.end_span(span)) } Kind::Undefined => { self.bump_any(); - Some(self.ast.ts_undefined_keyword(self.end_span(span))) + self.ast.ts_undefined_keyword(self.end_span(span)) } Kind::Unknown => { self.bump_any(); - Some(self.ast.ts_unknown_keyword(self.end_span(span))) + self.ast.ts_unknown_keyword(self.end_span(span)) } Kind::Void => { self.bump_any(); - Some(self.ast.ts_void_keyword(self.end_span(span))) + self.ast.ts_void_keyword(self.end_span(span)) } - _ => None, + _ => return Err(self.unexpected()), }; if self.at(Kind::Dot) { return Err(self.unexpected()); @@ -1053,11 +1054,11 @@ impl<'a> ParserImpl<'a> { let type_predicate_variable = if self.cur_kind().is_identifier_name() { self.try_parse(Self::parse_type_predicate_prefix) } else { - Ok(None) + None }; let type_span = self.start_span(); let ty = self.parse_ts_type()?; - if let Ok(Some(id)) = type_predicate_variable { + if let Some(id) = type_predicate_variable { let type_annotation = Some(self.ast.ts_type_annotation(self.end_span(type_span), ty)); let parameter_name = self.ast.ts_type_predicate_name_identifier(id); return Ok(self.ast.ts_type_predicate( @@ -1070,12 +1071,12 @@ impl<'a> ParserImpl<'a> { Ok(ty) } - fn parse_type_predicate_prefix(&mut self) -> Result>> { + fn parse_type_predicate_prefix(&mut self) -> Result> { let id = self.parse_identifier_name()?; let token = self.cur_token(); if token.kind == Kind::Is && !token.is_on_new_line { self.bump_any(); - return Ok(Some(id)); + return Ok(id); } Err(self.unexpected()) }