mirror of
https://github.com/danbulant/oxc
synced 2026-05-19 12:19:15 +00:00
refactor(parser): clean up try_parse (#3925)
This commit is contained in:
parent
253410017f
commit
a471e62e2d
5 changed files with 40 additions and 33 deletions
|
|
@ -297,15 +297,17 @@ impl<'a> ParserImpl<'a> {
|
|||
pub(crate) fn try_parse<T>(
|
||||
&mut self,
|
||||
func: impl FnOnce(&mut ParserImpl<'a>) -> Result<T>,
|
||||
) -> Result<T> {
|
||||
) -> Option<T> {
|
||||
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<U>(&mut self, predicate: impl Fn(&mut ParserImpl<'a>) -> U) -> U {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<Expression<'a>> {
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Option<TSType<'a>>> {
|
||||
fn parse_keyword_and_no_dot(&mut self) -> Result<TSType<'a>> {
|
||||
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<Option<IdentifierName<'a>>> {
|
||||
fn parse_type_predicate_prefix(&mut self) -> Result<IdentifierName<'a>> {
|
||||
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())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue