refactor(parser): clean up try_parse (#3925)

This commit is contained in:
Boshen 2024-06-26 11:18:01 +00:00
parent 253410017f
commit a471e62e2d
5 changed files with 40 additions and 33 deletions

View file

@ -297,15 +297,17 @@ impl<'a> ParserImpl<'a> {
pub(crate) fn try_parse<T>( pub(crate) fn try_parse<T>(
&mut self, &mut self,
func: impl FnOnce(&mut ParserImpl<'a>) -> Result<T>, func: impl FnOnce(&mut ParserImpl<'a>) -> Result<T>,
) -> Result<T> { ) -> Option<T> {
let checkpoint = self.checkpoint(); let checkpoint = self.checkpoint();
let ctx = self.ctx; let ctx = self.ctx;
let result = func(self); let result = func(self);
if result.is_err() { if let Ok(result) = result {
Some(result)
} else {
self.ctx = ctx; self.ctx = ctx;
self.rewind(checkpoint); self.rewind(checkpoint);
None
} }
result
} }
pub(crate) fn lookahead<U>(&mut self, predicate: impl Fn(&mut ParserImpl<'a>) -> U) -> U { pub(crate) fn lookahead<U>(&mut self, predicate: impl Fn(&mut ParserImpl<'a>) -> U) -> U {

View file

@ -328,7 +328,7 @@ impl<'a> ParserImpl<'a> {
if self.state.not_parenthesized_arrow.contains(&pos) { if self.state.not_parenthesized_arrow.contains(&pos) {
return Ok(None); 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) self.try_parse(ParserImpl::parse_parenthesized_arrow_function_head)
{ {
return self return self

View file

@ -164,7 +164,7 @@ impl<'a> ParserImpl<'a> {
return self.parse_function_expression(span, r#async); 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 Kind::Ident => self.parse_identifier_expression(), // fast path, keywords are checked at the end
// Literal, RegularExpressionLiteral // Literal, RegularExpressionLiteral
kind if kind.is_literal() => self.parse_literal_expression(), kind if kind.is_literal() => self.parse_literal_expression(),
@ -530,8 +530,8 @@ impl<'a> ParserImpl<'a> {
in_optional_chain: &mut bool, in_optional_chain: &mut bool,
) -> Result<Expression<'a>> { ) -> Result<Expression<'a>> {
let span = self.start_span(); let span = self.start_span();
self.parse_primary_expression() let lhs = self.parse_primary_expression()?;
.and_then(|lhs| self.parse_member_expression_rest(span, lhs, in_optional_chain)) self.parse_member_expression_rest(span, lhs, in_optional_chain)
} }
/// Section 13.3 Super Call /// 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)? self.parse_tagged_template(lhs_span, expr, *in_optional_chain, type_parameters)?
} }
Kind::LAngle | Kind::ShiftLeft => { Kind::LAngle | Kind::ShiftLeft => {
if let Ok(Some(arguments)) = if let Some(Some(arguments)) =
self.try_parse(Self::parse_type_arguments_in_expression) self.try_parse(Self::parse_type_arguments_in_expression)
{ {
lhs = self.ast.ts_instantiation_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 }; *in_optional_chain = if optional_call { true } else { *in_optional_chain };
if optional_call { 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); type_arguments = Some(args);
} }
if self.cur_kind().is_template_start_of_tagged_template() { if self.cur_kind().is_template_start_of_tagged_template() {

View file

@ -417,6 +417,10 @@ impl<'a> ParserImpl<'a> {
self.errors.push(error); self.errors.push(error);
} }
fn errors_count(&self) -> usize {
self.errors.len() + self.lexer.errors.len()
}
fn ts_enabled(&self) -> bool { fn ts_enabled(&self) -> bool {
self.source_type.is_typescript() self.source_type.is_typescript()
} }

View file

@ -129,10 +129,11 @@ impl<'a> ParserImpl<'a> {
self.bump_any(); self.bump_any();
return true; return true;
} }
if matches!(self.cur_kind(), Kind::LBrack | Kind::LCurly) if matches!(self.cur_kind(), Kind::LBrack | Kind::LCurly) {
&& self.parse_binding_pattern_kind().is_ok() let errors_count = self.errors_count();
{ if self.parse_binding_pattern_kind().is_ok() && errors_count == self.errors_count() {
return true; return true;
}
} }
false false
} }
@ -342,7 +343,7 @@ impl<'a> ParserImpl<'a> {
| Kind::Undefined | Kind::Undefined
| Kind::Never | Kind::Never
| Kind::Object => { | 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) Ok(ty)
} else { } else {
self.parse_type_reference() self.parse_type_reference()
@ -421,62 +422,62 @@ impl<'a> ParserImpl<'a> {
} }
} }
fn parse_keyword_and_no_dot(&mut self) -> Result<Option<TSType<'a>>> { fn parse_keyword_and_no_dot(&mut self) -> Result<TSType<'a>> {
let span = self.start_span(); let span = self.start_span();
let ty = match self.cur_kind() { let ty = match self.cur_kind() {
Kind::Any => { Kind::Any => {
self.bump_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 => { Kind::BigInt => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_bigint_keyword(self.end_span(span))) self.ast.ts_bigint_keyword(self.end_span(span))
} }
Kind::Boolean => { Kind::Boolean => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_boolean_keyword(self.end_span(span))) self.ast.ts_boolean_keyword(self.end_span(span))
} }
Kind::Intrinsic => { Kind::Intrinsic => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_intrinsic_keyword(self.end_span(span))) self.ast.ts_intrinsic_keyword(self.end_span(span))
} }
Kind::Never => { Kind::Never => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_never_keyword(self.end_span(span))) self.ast.ts_never_keyword(self.end_span(span))
} }
Kind::Null => { Kind::Null => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_null_keyword(self.end_span(span))) self.ast.ts_null_keyword(self.end_span(span))
} }
Kind::Number => { Kind::Number => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_number_keyword(self.end_span(span))) self.ast.ts_number_keyword(self.end_span(span))
} }
Kind::Object => { Kind::Object => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_object_keyword(self.end_span(span))) self.ast.ts_object_keyword(self.end_span(span))
} }
Kind::String => { Kind::String => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_string_keyword(self.end_span(span))) self.ast.ts_string_keyword(self.end_span(span))
} }
Kind::Symbol => { Kind::Symbol => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_symbol_keyword(self.end_span(span))) self.ast.ts_symbol_keyword(self.end_span(span))
} }
Kind::Undefined => { Kind::Undefined => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_undefined_keyword(self.end_span(span))) self.ast.ts_undefined_keyword(self.end_span(span))
} }
Kind::Unknown => { Kind::Unknown => {
self.bump_any(); self.bump_any();
Some(self.ast.ts_unknown_keyword(self.end_span(span))) self.ast.ts_unknown_keyword(self.end_span(span))
} }
Kind::Void => { Kind::Void => {
self.bump_any(); 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) { if self.at(Kind::Dot) {
return Err(self.unexpected()); return Err(self.unexpected());
@ -1053,11 +1054,11 @@ impl<'a> ParserImpl<'a> {
let type_predicate_variable = if self.cur_kind().is_identifier_name() { let type_predicate_variable = if self.cur_kind().is_identifier_name() {
self.try_parse(Self::parse_type_predicate_prefix) self.try_parse(Self::parse_type_predicate_prefix)
} else { } else {
Ok(None) None
}; };
let type_span = self.start_span(); let type_span = self.start_span();
let ty = self.parse_ts_type()?; 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 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); let parameter_name = self.ast.ts_type_predicate_name_identifier(id);
return Ok(self.ast.ts_type_predicate( return Ok(self.ast.ts_type_predicate(
@ -1070,12 +1071,12 @@ impl<'a> ParserImpl<'a> {
Ok(ty) Ok(ty)
} }
fn parse_type_predicate_prefix(&mut self) -> Result<Option<IdentifierName<'a>>> { fn parse_type_predicate_prefix(&mut self) -> Result<IdentifierName<'a>> {
let id = self.parse_identifier_name()?; let id = self.parse_identifier_name()?;
let token = self.cur_token(); let token = self.cur_token();
if token.kind == Kind::Is && !token.is_on_new_line { if token.kind == Kind::Is && !token.is_on_new_line {
self.bump_any(); self.bump_any();
return Ok(Some(id)); return Ok(id);
} }
Err(self.unexpected()) Err(self.unexpected())
} }