diff --git a/crates/oxc_parser/src/cursor.rs b/crates/oxc_parser/src/cursor.rs index 9626412a2c21b..b06c5c3204153 100644 --- a/crates/oxc_parser/src/cursor.rs +++ b/crates/oxc_parser/src/cursor.rs @@ -28,9 +28,7 @@ impl<'a> ParserImpl<'a> { #[inline] pub(crate) fn end_span(&self, start: u32) -> Span { - let end = self.prev_token_end; - debug_assert!(end >= start); - Span::new(start, end) + Span::new(start, self.prev_token_end) } /// Get current token @@ -168,16 +166,16 @@ impl<'a> ParserImpl<'a> { /// [Automatic Semicolon Insertion](https://tc39.es/ecma262/#sec-automatic-semicolon-insertion) /// # Errors - pub(crate) fn asi(&mut self) -> Result<()> { + pub(crate) fn asi(&mut self) { if !self.can_insert_semicolon() { let span = Span::new(self.prev_token_end, self.prev_token_end); let error = diagnostics::auto_semicolon_insertion(span); - return Err(self.set_fatal_error(error)); + self.set_fatal_error(error); + return; } if self.at(Kind::Semicolon) { self.advance(Kind::Semicolon); } - Ok(()) } pub(crate) fn can_insert_semicolon(&self) -> bool { @@ -189,39 +187,35 @@ impl<'a> ParserImpl<'a> { } /// # Errors - pub(crate) fn expect_without_advance(&mut self, kind: Kind) -> Result<()> { + pub(crate) fn expect_without_advance(&mut self, kind: Kind) { if !self.at(kind) { let range = self.cur_token().span(); let error = diagnostics::expect_token(kind.to_str(), self.cur_kind().to_str(), range); - return Err(self.set_fatal_error(error)); + self.set_fatal_error(error); } - Ok(()) } /// Expect a `Kind` or return error /// # Errors #[inline] - pub(crate) fn expect(&mut self, kind: Kind) -> Result<()> { - self.expect_without_advance(kind)?; + pub(crate) fn expect(&mut self, kind: Kind) { + self.expect_without_advance(kind); self.advance(kind); - Ok(()) } /// Expect the next next token to be a `JsxChild`, i.e. `<` or `{` or `JSXText` /// # Errors - pub(crate) fn expect_jsx_child(&mut self, kind: Kind) -> Result<()> { - self.expect_without_advance(kind)?; + pub(crate) fn expect_jsx_child(&mut self, kind: Kind) { + self.expect_without_advance(kind); self.advance_for_jsx_child(kind); - Ok(()) } /// Expect the next next token to be a `JsxString` or any other token /// # Errors - pub(crate) fn expect_jsx_attribute_value(&mut self, kind: Kind) -> Result<()> { + pub(crate) fn expect_jsx_attribute_value(&mut self, kind: Kind) { self.lexer.set_context(LexerContext::JsxAttributeValue); - self.expect(kind)?; + self.expect(kind); self.lexer.set_context(LexerContext::Regular); - Ok(()) } /// Tell lexer to read a regex @@ -296,16 +290,15 @@ impl<'a> ParserImpl<'a> { self.fatal_error = fatal_error; } - /// # Errors pub(crate) fn try_parse( &mut self, - func: impl FnOnce(&mut ParserImpl<'a>) -> Result, + func: impl FnOnce(&mut ParserImpl<'a>) -> T, ) -> Option { let checkpoint = self.checkpoint(); let ctx = self.ctx; - let result = func(self); - if let Ok(result) = result { - Some(result) + let node = func(self); + if self.fatal_error.is_none() { + Some(node) } else { self.ctx = ctx; self.rewind(checkpoint); @@ -337,33 +330,28 @@ impl<'a> ParserImpl<'a> { self.state.decorators.take_in(self.ast.allocator) } - pub(crate) fn parse_normal_list( - &mut self, - open: Kind, - close: Kind, - f: F, - ) -> Result> + pub(crate) fn parse_normal_list(&mut self, open: Kind, close: Kind, f: F) -> Vec<'a, T> where - F: Fn(&mut Self) -> Result>, + F: Fn(&mut Self) -> Option, { - self.expect(open)?; + self.expect(open); let mut list = self.ast.vec(); loop { let kind = self.cur_kind(); if kind == close || self.has_fatal_error() { break; } - match f(self)? { + match f(self) { Some(e) => { list.push(e); } - _ => { + None => { break; } } } - self.expect(close)?; - Ok(list) + self.expect(close); + list } pub(crate) fn parse_delimited_list( @@ -372,9 +360,9 @@ impl<'a> ParserImpl<'a> { separator: Kind, trailing_separator: bool, f: F, - ) -> Result> + ) -> Vec<'a, T> where - F: Fn(&mut Self) -> Result, + F: Fn(&mut Self) -> T, { let mut list = self.ast.vec(); let mut first = true; @@ -389,14 +377,14 @@ impl<'a> ParserImpl<'a> { if !trailing_separator && self.at(separator) && self.peek_at(close) { break; } - self.expect(separator)?; + self.expect(separator); if self.at(close) { break; } } - list.push(f(self)?); + list.push(f(self)); } - Ok(list) + list } pub(crate) fn parse_delimited_list_with_rest( @@ -404,10 +392,10 @@ impl<'a> ParserImpl<'a> { close: Kind, parse_element: E, parse_rest: R, - ) -> Result<(Vec<'a, A>, Option)> + ) -> (Vec<'a, A>, Option) where - E: Fn(&mut Self) -> Result, - R: Fn(&mut Self) -> Result, + E: Fn(&mut Self) -> A, + R: Fn(&mut Self) -> B, B: GetSpan, { let mut list = self.ast.vec(); @@ -421,20 +409,20 @@ impl<'a> ParserImpl<'a> { if first { first = false; } else { - self.expect(Kind::Comma)?; + self.expect(Kind::Comma); if self.at(close) { break; } } if self.at(Kind::Dot3) { - if let Some(r) = rest.replace(parse_rest(self)?) { + if let Some(r) = rest.replace(parse_rest(self)) { self.error(diagnostics::binding_rest_element_last(r.span())); } } else { - list.push(parse_element(self)?); + list.push(parse_element(self)); } } - Ok((list, rest)) + (list, rest) } } diff --git a/crates/oxc_parser/src/error_handler.rs b/crates/oxc_parser/src/error_handler.rs index 3c515314a4f41..8c461a93377d9 100644 --- a/crates/oxc_parser/src/error_handler.rs +++ b/crates/oxc_parser/src/error_handler.rs @@ -11,21 +11,21 @@ pub struct FatalError { /// The fatal error pub error: OxcDiagnostic, /// Length of `errors` at time fatal error is recorded - #[expect(unused)] pub errors_len: usize, } impl<'a> ParserImpl<'a> { - pub(crate) fn set_unexpected(&mut self) -> OxcDiagnostic { + pub(crate) fn set_unexpected(&mut self) { // The lexer should have reported a more meaningful diagnostic // when it is a undetermined kind. if matches!(self.cur_kind(), Kind::Eof | Kind::Undetermined) { if let Some(error) = self.lexer.errors.pop() { - return self.set_fatal_error(error); + self.set_fatal_error(error); + return; } } let error = diagnostics::unexpected_token(self.cur_token().span()); - self.set_fatal_error(error) + self.set_fatal_error(error); } /// Return error info at current token @@ -33,9 +33,10 @@ impl<'a> ParserImpl<'a> { /// # Panics /// /// * The lexer did not push a diagnostic when `Kind::Undetermined` is returned - pub(crate) fn unexpected(&mut self) -> OxcDiagnostic { - self.set_unexpected() - // Dummy::dummy(self.ast.allocator) + #[must_use] + pub(crate) fn unexpected>(&mut self) -> T { + self.set_unexpected(); + Dummy::dummy(self.ast.allocator) } /// Push a Syntax Error @@ -49,18 +50,15 @@ impl<'a> ParserImpl<'a> { } /// Advance lexer's cursor to end of file. - pub(crate) fn set_fatal_error(&mut self, error: OxcDiagnostic) -> OxcDiagnostic { + pub(crate) fn set_fatal_error(&mut self, error: OxcDiagnostic) { if self.fatal_error.is_none() { self.lexer.advance_to_end(); - self.fatal_error = - Some(FatalError { error: error.clone(), errors_len: self.errors.len() }); + self.fatal_error = Some(FatalError { error, errors_len: self.errors.len() }); } - error } - #[expect(unused)] pub(crate) fn fatal_error>(&mut self, error: OxcDiagnostic) -> T { - let _ = self.set_fatal_error(error); + self.set_fatal_error(error); Dummy::dummy(self.ast.allocator) } diff --git a/crates/oxc_parser/src/js/arrow.rs b/crates/oxc_parser/src/js/arrow.rs index f9d993aabd964..5457be3739be1 100644 --- a/crates/oxc_parser/src/js/arrow.rs +++ b/crates/oxc_parser/src/js/arrow.rs @@ -1,6 +1,5 @@ use oxc_allocator::Box; use oxc_ast::{NONE, ast::*}; -use oxc_diagnostics::Result; use oxc_span::GetSpan; use oxc_syntax::precedence::Precedence; @@ -20,12 +19,12 @@ impl<'a> ParserImpl<'a> { pub(super) fn try_parse_parenthesized_arrow_function_expression( &mut self, allow_return_type_in_arrow_function: bool, - ) -> Result>> { + ) -> Option> { match self.is_parenthesized_arrow_function_expression() { - Tristate::False => Ok(None), - Tristate::True => self.parse_parenthesized_arrow_function_expression( + Tristate::False => None, + Tristate::True => Some(self.parse_parenthesized_arrow_function_expression( /* allow_return_type_in_arrow_function */ true, - ), + )), Tristate::Maybe => self.parse_possible_parenthesized_arrow_function_expression( allow_return_type_in_arrow_function, ), @@ -35,23 +34,21 @@ impl<'a> ParserImpl<'a> { pub(super) fn try_parse_async_simple_arrow_function_expression( &mut self, allow_return_type_in_arrow_function: bool, - ) -> Result>> { + ) -> Option> { if self.at(Kind::Async) && self.is_un_parenthesized_async_arrow_function_worker() == Tristate::True { let span = self.start_span(); self.bump_any(); // bump `async` - let expr = self.parse_binary_expression_or_higher(Precedence::Comma)?; - return self - .parse_simple_arrow_function_expression( - span, - expr, - /* async */ true, - allow_return_type_in_arrow_function, - ) - .map(Some); + let expr = self.parse_binary_expression_or_higher(Precedence::Comma); + return Some(self.parse_simple_arrow_function_expression( + span, + expr, + /* async */ true, + allow_return_type_in_arrow_function, + )); } - Ok(None) + None } fn is_parenthesized_arrow_function_expression(&mut self) -> Tristate { @@ -217,7 +214,7 @@ impl<'a> ParserImpl<'a> { ident: Expression<'a>, r#async: bool, allow_return_type_in_arrow_function: bool, - ) -> Result> { + ) -> Expression<'a> { let has_await = self.ctx.has_await(); self.ctx = self.ctx.union_await_if(r#async); @@ -247,7 +244,7 @@ impl<'a> ParserImpl<'a> { self.error(diagnostics::lineterminator_before_arrow(self.cur_token().span())); } - self.expect(Kind::Arrow)?; + self.expect(Kind::Arrow); self.parse_arrow_function_expression_body( ArrowFunctionHead { @@ -262,17 +259,17 @@ impl<'a> ParserImpl<'a> { ) } - fn parse_parenthesized_arrow_function_head(&mut self) -> Result> { + fn parse_parenthesized_arrow_function_head(&mut self) -> ArrowFunctionHead<'a> { let span = self.start_span(); let r#async = self.eat(Kind::Async); let has_await = self.ctx.has_await(); self.ctx = self.ctx.union_await_if(r#async); - let type_parameters = self.parse_ts_type_parameters()?; + let type_parameters = self.parse_ts_type_parameters(); let (this_param, params) = - self.parse_formal_parameters(FormalParameterKind::ArrowFormalParameters)?; + self.parse_formal_parameters(FormalParameterKind::ArrowFormalParameters); if let Some(this_param) = this_param { // const x = (this: number) => {}; @@ -280,7 +277,7 @@ impl<'a> ParserImpl<'a> { } let has_return_colon = self.is_ts && self.at(Kind::Colon); - let return_type = self.parse_ts_return_type_annotation(Kind::Arrow, false)?; + let return_type = self.parse_ts_return_type_annotation(Kind::Arrow, false); self.ctx = self.ctx.and_await(has_await); @@ -288,16 +285,9 @@ impl<'a> ParserImpl<'a> { self.error(diagnostics::lineterminator_before_arrow(self.cur_token().span())); } - self.expect(Kind::Arrow)?; + self.expect(Kind::Arrow); - Ok(ArrowFunctionHead { - type_parameters, - params, - return_type, - r#async, - span, - has_return_colon, - }) + ArrowFunctionHead { type_parameters, params, return_type, r#async, span, has_return_colon } } /// [ConciseBody](https://tc39.es/ecma262/#prod-ConciseBody) @@ -309,7 +299,7 @@ impl<'a> ParserImpl<'a> { &mut self, arrow_function_head: ArrowFunctionHead<'a>, allow_return_type_in_arrow_function: bool, - ) -> Result> { + ) -> Expression<'a> { let ArrowFunctionHead { type_parameters, params, return_type, r#async, span, .. } = arrow_function_head; let has_await = self.ctx.has_await(); @@ -319,17 +309,17 @@ impl<'a> ParserImpl<'a> { let expression = !self.at(Kind::LCurly); let body = if expression { let expr = self - .parse_assignment_expression_or_higher_impl(allow_return_type_in_arrow_function)?; + .parse_assignment_expression_or_higher_impl(allow_return_type_in_arrow_function); let span = expr.span(); let expr_stmt = self.ast.statement_expression(span, expr); self.ast.alloc_function_body(span, self.ast.vec(), self.ast.vec1(expr_stmt)) } else { - self.parse_function_body()? + self.parse_function_body() }; self.ctx = self.ctx.and_await(has_await).and_yield(has_yield); - Ok(self.ast.expression_arrow_function( + self.ast.expression_arrow_function( self.end_span(span), expression, r#async, @@ -337,7 +327,7 @@ impl<'a> ParserImpl<'a> { params, return_type, body, - )) + ) } /// Section [Arrow Function](https://tc39.es/ecma262/#sec-arrow-function-definitions) @@ -346,33 +336,33 @@ impl<'a> ParserImpl<'a> { fn parse_parenthesized_arrow_function_expression( &mut self, allow_return_type_in_arrow_function: bool, - ) -> Result>> { - let head = self.parse_parenthesized_arrow_function_head()?; + ) -> Expression<'a> { + let head = self.parse_parenthesized_arrow_function_head(); self.parse_arrow_function_expression_body(head, allow_return_type_in_arrow_function) - .map(Some) } fn parse_possible_parenthesized_arrow_function_expression( &mut self, allow_return_type_in_arrow_function: bool, - ) -> Result>> { + ) -> Option> { let pos = self.cur_token().start; if self.state.not_parenthesized_arrow.contains(&pos) { - return Ok(None); + return None; } let checkpoint = self.checkpoint(); - let Ok(head) = self.parse_parenthesized_arrow_function_head() else { + let head = self.parse_parenthesized_arrow_function_head(); + if self.has_fatal_error() { self.state.not_parenthesized_arrow.insert(pos); self.rewind(checkpoint); - return Ok(None); - }; + return None; + } let has_return_colon = head.has_return_colon; let body = - self.parse_arrow_function_expression_body(head, allow_return_type_in_arrow_function)?; + self.parse_arrow_function_expression_body(head, allow_return_type_in_arrow_function); // Given: // x ? y => ({ y }) : z => ({ z }) @@ -399,10 +389,10 @@ impl<'a> ParserImpl<'a> { if !self.at(Kind::Colon) { self.state.not_parenthesized_arrow.insert(pos); self.rewind(checkpoint); - return Ok(None); + return None; } } - Ok(Some(body)) + Some(body) } } diff --git a/crates/oxc_parser/src/js/binding.rs b/crates/oxc_parser/src/js/binding.rs index 6002ba1652348..d8d4e7084576c 100644 --- a/crates/oxc_parser/src/js/binding.rs +++ b/crates/oxc_parser/src/js/binding.rs @@ -1,5 +1,4 @@ use oxc_ast::{NONE, ast::*}; -use oxc_diagnostics::Result; use oxc_span::GetSpan; use crate::{Context, ParserImpl, diagnostics, lexer::Kind}; @@ -8,28 +7,25 @@ impl<'a> ParserImpl<'a> { /// `BindingElement` /// `SingleNameBinding` /// `BindingPattern`[?Yield, ?Await] `Initializer`[+In, ?Yield, ?Await]opt - pub(super) fn parse_binding_pattern_with_initializer(&mut self) -> Result> { + pub(super) fn parse_binding_pattern_with_initializer(&mut self) -> BindingPattern<'a> { let span = self.start_span(); - let pattern = self.parse_binding_pattern(true)?; + let pattern = self.parse_binding_pattern(true); self.context(Context::In, Context::empty(), |p| p.parse_initializer(span, pattern)) } - pub(super) fn parse_binding_pattern( - &mut self, - allow_question: bool, - ) -> Result> { - let mut kind = self.parse_binding_pattern_kind()?; + pub(super) fn parse_binding_pattern(&mut self, allow_question: bool) -> BindingPattern<'a> { + let mut kind = self.parse_binding_pattern_kind(); let optional = if allow_question && self.is_ts { self.eat(Kind::Question) } else { false }; - let type_annotation = self.parse_ts_type_annotation()?; + let type_annotation = self.parse_ts_type_annotation(); if let Some(type_annotation) = &type_annotation { Self::extend_binding_pattern_span_end(type_annotation.span.end, &mut kind); } else if optional { Self::extend_binding_pattern_span_end(self.prev_token_end, &mut kind); } - Ok(self.ast.binding_pattern(kind, type_annotation, optional)) + self.ast.binding_pattern(kind, type_annotation, optional) } - pub(crate) fn parse_binding_pattern_kind(&mut self) -> Result> { + pub(crate) fn parse_binding_pattern_kind(&mut self) -> BindingPatternKind<'a> { match self.cur_kind() { Kind::LCurly => self.parse_object_binding_pattern(), Kind::LBrack => self.parse_array_binding_pattern(), @@ -37,61 +33,61 @@ impl<'a> ParserImpl<'a> { } } - fn parse_binding_pattern_identifier(&mut self) -> Result> { - let ident = self.parse_binding_identifier()?; - Ok(BindingPatternKind::BindingIdentifier(self.alloc(ident))) + fn parse_binding_pattern_identifier(&mut self) -> BindingPatternKind<'a> { + let ident = self.parse_binding_identifier(); + BindingPatternKind::BindingIdentifier(self.alloc(ident)) } /// Section 14.3.3 Object Binding Pattern - fn parse_object_binding_pattern(&mut self) -> Result> { + fn parse_object_binding_pattern(&mut self) -> BindingPatternKind<'a> { let span = self.start_span(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let (list, rest) = self.parse_delimited_list_with_rest( Kind::RCurly, Self::parse_binding_property, Self::parse_rest_binding, - )?; + ); if let Some(rest) = &rest { if !matches!(&rest.argument.kind, BindingPatternKind::BindingIdentifier(_)) { let error = diagnostics::invalid_binding_rest_element(rest.argument.span()); - return Err(self.set_fatal_error(error)); + return self.fatal_error(error); } } - self.expect(Kind::RCurly)?; - Ok(self.ast.binding_pattern_kind_object_pattern( + self.expect(Kind::RCurly); + self.ast.binding_pattern_kind_object_pattern( self.end_span(span), list, rest.map(|r| self.alloc(r)), - )) + ) } /// Section 14.3.3 Array Binding Pattern - fn parse_array_binding_pattern(&mut self) -> Result> { + fn parse_array_binding_pattern(&mut self) -> BindingPatternKind<'a> { let span = self.start_span(); - self.expect(Kind::LBrack)?; + self.expect(Kind::LBrack); let (list, rest) = self.parse_delimited_list_with_rest( Kind::RBrack, Self::parse_array_binding_element, Self::parse_rest_binding, - )?; - self.expect(Kind::RBrack)?; - Ok(self.ast.binding_pattern_kind_array_pattern( + ); + self.expect(Kind::RBrack); + self.ast.binding_pattern_kind_array_pattern( self.end_span(span), list, rest.map(|r| self.alloc(r)), - )) + ) } - fn parse_array_binding_element(&mut self) -> Result>> { + fn parse_array_binding_element(&mut self) -> Option> { if self.at(Kind::Comma) { - Ok(None) + None } else { - self.parse_binding_pattern_with_initializer().map(Some) + Some(self.parse_binding_pattern_with_initializer()) } } - fn parse_rest_binding(&mut self) -> Result> { - let elem = self.parse_rest_element()?; + fn parse_rest_binding(&mut self) -> BindingRestElement<'a> { + let elem = self.parse_rest_element(); if let Some(ty) = &elem.argument.type_annotation { self.error(diagnostics::rest_element_property_name(ty.span)); } @@ -105,16 +101,16 @@ impl<'a> ParserImpl<'a> { self.error(diagnostics::binding_rest_element_last(elem.span)); } } - Ok(elem) + elem } /// Section 14.3.3 Binding Rest Property - pub(super) fn parse_rest_element(&mut self) -> Result> { + pub(super) fn parse_rest_element(&mut self) -> BindingRestElement<'a> { let span = self.start_span(); self.bump_any(); // advance `...` let init_span = self.start_span(); - let kind = self.parse_binding_pattern_kind()?; + let kind = self.parse_binding_pattern_kind(); // Rest element does not allow `?`, checked in checker/typescript.rs if self.at(Kind::Question) && self.is_ts { let span = self.cur_token().span(); @@ -122,30 +118,30 @@ impl<'a> ParserImpl<'a> { self.error(diagnostics::a_rest_parameter_cannot_be_optional(span)); } // The span is not extended to its type_annotation - let type_annotation = self.parse_ts_type_annotation()?; + let type_annotation = self.parse_ts_type_annotation(); let pattern = self.ast.binding_pattern(kind, type_annotation, false); // Rest element does not allow `= initializer` // function foo([...x = []]) { } // ^^^^ A rest element cannot have an initializer let argument = self - .context(Context::In, Context::empty(), |p| p.parse_initializer(init_span, pattern))?; + .context(Context::In, Context::empty(), |p| p.parse_initializer(init_span, pattern)); if let BindingPatternKind::AssignmentPattern(pat) = &argument.kind { self.error(diagnostics::a_rest_element_cannot_have_an_initializer(pat.span)); } - Ok(self.ast.binding_rest_element(self.end_span(span), argument)) + self.ast.binding_rest_element(self.end_span(span), argument) } /// `BindingProperty`[Yield, Await] : /// `SingleNameBinding`[?Yield, ?Await] /// `PropertyName`[?Yield, ?Await] : `BindingElement`[?Yield, ?Await] - pub(super) fn parse_binding_property(&mut self) -> Result> { + pub(super) fn parse_binding_property(&mut self) -> BindingProperty<'a> { let span = self.start_span(); let mut shorthand = false; let is_binding_identifier = self.cur_kind().is_binding_identifier(); - let (key, computed) = self.parse_property_name()?; + let (key, computed) = self.parse_property_name(); let value = if is_binding_identifier && !self.at(Kind::Colon) { // let { a = b } = c @@ -156,36 +152,32 @@ impl<'a> ParserImpl<'a> { let identifier = self.ast.binding_pattern_kind_binding_identifier(ident.span, ident.name); let left = self.ast.binding_pattern(identifier, NONE, false); - self.context(Context::In, Context::empty(), |p| p.parse_initializer(span, left))? + self.context(Context::In, Context::empty(), |p| p.parse_initializer(span, left)) } else { - return Err(self.unexpected()); + return self.unexpected(); } } else { // let { a: b } = c // ^ IdentifierReference - self.expect(Kind::Colon)?; - self.parse_binding_pattern_with_initializer()? + self.expect(Kind::Colon); + self.parse_binding_pattern_with_initializer() }; - Ok(self.ast.binding_property(self.end_span(span), key, value, shorthand, computed)) + self.ast.binding_property(self.end_span(span), key, value, shorthand, computed) } /// Initializer[In, Yield, Await] : /// = `AssignmentExpression`[?In, ?Yield, ?Await] - fn parse_initializer( - &mut self, - span: u32, - left: BindingPattern<'a>, - ) -> Result> { + fn parse_initializer(&mut self, span: u32, left: BindingPattern<'a>) -> BindingPattern<'a> { if self.eat(Kind::Eq) { - let expr = self.parse_assignment_expression_or_higher()?; - Ok(self.ast.binding_pattern( + let expr = self.parse_assignment_expression_or_higher(); + self.ast.binding_pattern( self.ast.binding_pattern_kind_assignment_pattern(self.end_span(span), left, expr), NONE, false, - )) + ) } else { - Ok(left) + left } } diff --git a/crates/oxc_parser/src/js/class.rs b/crates/oxc_parser/src/js/class.rs index cfc18ffbd5d38..07f5ef6041105 100644 --- a/crates/oxc_parser/src/js/class.rs +++ b/crates/oxc_parser/src/js/class.rs @@ -1,6 +1,5 @@ use oxc_allocator::{Box, Vec}; use oxc_ast::ast::*; -use oxc_diagnostics::Result; use oxc_ecmascript::PropName; use oxc_span::{GetSpan, Span}; @@ -20,12 +19,12 @@ impl<'a> ParserImpl<'a> { &mut self, stmt_ctx: StatementContext, start_span: u32, - ) -> Result> { + ) -> Statement<'a> { let modifiers = self.parse_modifiers( /* allow_decorators */ true, /* permit_const_as_modifier */ false, /* stop_on_start_of_class_static_block */ true, ); - let decl = self.parse_class_declaration(start_span, &modifiers)?; + let decl = self.parse_class_declaration(start_span, &modifiers); if stmt_ctx.is_single_statement() { self.error(diagnostics::class_declaration(Span::new( @@ -34,7 +33,7 @@ impl<'a> ParserImpl<'a> { ))); } - Ok(Statement::ClassDeclaration(decl)) + Statement::ClassDeclaration(decl) } /// Section 15.7 Class Definitions @@ -42,17 +41,17 @@ impl<'a> ParserImpl<'a> { &mut self, start_span: u32, modifiers: &Modifiers<'a>, - ) -> Result>> { + ) -> Box<'a, Class<'a>> { self.parse_class(start_span, ClassType::ClassDeclaration, modifiers) } /// Section [Class Definitions](https://tc39.es/ecma262/#prod-ClassExpression) /// `ClassExpression`[Yield, Await] : /// class `BindingIdentifier`[?Yield, ?Await]opt `ClassTail`[?Yield, ?Await] - pub(crate) fn parse_class_expression(&mut self) -> Result> { + pub(crate) fn parse_class_expression(&mut self) -> Expression<'a> { let class = - self.parse_class(self.start_span(), ClassType::ClassExpression, &Modifiers::empty())?; - Ok(Expression::ClassExpression(class)) + self.parse_class(self.start_span(), ClassType::ClassExpression, &Modifiers::empty()); + Expression::ClassExpression(class) } fn parse_class( @@ -60,7 +59,7 @@ impl<'a> ParserImpl<'a> { start_span: u32, r#type: ClassType, modifiers: &Modifiers<'a>, - ) -> Result>> { + ) -> Box<'a, Class<'a>> { self.bump_any(); // advance `class` let decorators = self.consume_decorators(); @@ -74,13 +73,13 @@ impl<'a> ParserImpl<'a> { } let id = if self.cur_kind().is_binding_identifier() && !self.at(Kind::Implements) { - Some(self.parse_binding_identifier()?) + Some(self.parse_binding_identifier()) } else { None }; - let type_parameters = if self.is_ts { self.parse_ts_type_parameters()? } else { None }; - let (extends, implements) = self.parse_heritage_clause()?; + let type_parameters = if self.is_ts { self.parse_ts_type_parameters() } else { None }; + let (extends, implements) = self.parse_heritage_clause(); let mut super_class = None; let mut super_type_parameters = None; if let Some(mut extends) = extends { @@ -90,7 +89,7 @@ impl<'a> ParserImpl<'a> { super_type_parameters = first_extends.1; } } - let body = self.parse_class_body()?; + let body = self.parse_class_body(); self.verify_modifiers( modifiers, @@ -98,7 +97,7 @@ impl<'a> ParserImpl<'a> { diagnostics::modifier_cannot_be_used_here, ); - Ok(self.ast.alloc_class( + self.ast.alloc_class( self.end_span(start_span), r#type, decorators, @@ -110,12 +109,12 @@ impl<'a> ParserImpl<'a> { body, modifiers.contains_abstract(), modifiers.contains_declare(), - )) + ) } pub(crate) fn parse_heritage_clause( &mut self, - ) -> Result<(Option>, Vec<'a, TSClassImplements<'a>>)> { + ) -> (Option>, Vec<'a, TSClassImplements<'a>>) { let mut extends = None; let mut implements = self.ast.vec(); @@ -131,7 +130,7 @@ impl<'a> ParserImpl<'a> { self.cur_token().span(), )); } - extends = Some(self.parse_extends_clause()?); + extends = Some(self.parse_extends_clause()); } Kind::Implements => { if !implements.is_empty() { @@ -139,31 +138,31 @@ impl<'a> ParserImpl<'a> { self.cur_token().span(), )); } - implements.extend(self.parse_ts_implements_clause()?); + implements.extend(self.parse_ts_implements_clause()); } _ => break, } } - Ok((extends, implements)) + (extends, implements) } /// `ClassHeritage` /// extends `LeftHandSideExpression`[?Yield, ?Await] - fn parse_extends_clause(&mut self) -> Result> { + fn parse_extends_clause(&mut self) -> Extends<'a> { self.bump_any(); // bump `extends` let mut extends = self.ast.vec(); loop { let span = self.start_span(); - let mut extend = self.parse_lhs_expression_or_higher()?; + let mut extend = self.parse_lhs_expression_or_higher(); let type_argument; if let Expression::TSInstantiationExpression(expr) = extend { let expr = expr.unbox(); extend = expr.expression; type_argument = Some(expr.type_arguments); } else { - type_argument = self.try_parse_type_arguments()?; + type_argument = self.try_parse_type_arguments(); } extends.push((extend, type_argument, self.end_span(span))); @@ -173,23 +172,23 @@ impl<'a> ParserImpl<'a> { } } - Ok(extends) + extends } - fn parse_class_body(&mut self) -> Result>> { + fn parse_class_body(&mut self) -> Box<'a, ClassBody<'a>> { let span = self.start_span(); let class_elements = - self.parse_normal_list(Kind::LCurly, Kind::RCurly, Self::parse_class_element)?; - Ok(self.ast.alloc_class_body(self.end_span(span), class_elements)) + self.parse_normal_list(Kind::LCurly, Kind::RCurly, Self::parse_class_element); + self.ast.alloc_class_body(self.end_span(span), class_elements) } - pub(crate) fn parse_class_element(&mut self) -> Result>> { + pub(crate) fn parse_class_element(&mut self) -> Option> { // skip empty class element `;` while self.at(Kind::Semicolon) { self.bump_any(); } if self.at(Kind::RCurly) { - return Ok(None); + return None; } let span = self.start_span(); @@ -214,7 +213,7 @@ impl<'a> ParserImpl<'a> { // static { block } if self.peek_at(Kind::LCurly) { self.bump(Kind::Static); - return self.parse_class_static_block(span).map(Some); + return Some(self.parse_class_static_block(span)); } // static ... @@ -222,7 +221,7 @@ impl<'a> ParserImpl<'a> { self.bump(Kind::Static); r#static = true; } else { - key_name = Some(self.parse_class_element_name()?); + key_name = Some(self.parse_class_element_name()); } } @@ -234,14 +233,13 @@ impl<'a> ParserImpl<'a> { self.bump(Kind::Async); r#async = true; } else { - key_name = Some(self.parse_class_element_name()?); + key_name = Some(self.parse_class_element_name()); } } if self.is_at_ts_index_signature_member() { - return self - .parse_index_signature_declaration(span, &modifiers) - .map(|sig| Some(ClassElement::TSIndexSignature(self.alloc(sig)))); + let decl = self.parse_index_signature_declaration(span, &modifiers); + return Some(ClassElement::TSIndexSignature(self.alloc(decl))); } // * ... @@ -256,22 +254,20 @@ impl<'a> ParserImpl<'a> { Kind::Get if peeked_class_element => { self.bump(Kind::Get); kind = MethodDefinitionKind::Get; - Some(self.parse_class_element_name()?) + Some(self.parse_class_element_name()) } Kind::Set if peeked_class_element => { self.bump(Kind::Set); kind = MethodDefinitionKind::Set; - Some(self.parse_class_element_name()?) + Some(self.parse_class_element_name()) } - kind if kind.is_class_element_name_start() => { - Some(self.parse_class_element_name()?) - } - _ => return Err(self.unexpected()), + kind if kind.is_class_element_name_start() => Some(self.parse_class_element_name()), + _ => return self.unexpected(), } } let (key, computed) = - if let Some(result) = key_name { result } else { self.parse_class_element_name()? }; + if let Some(result) = key_name { result } else { self.parse_class_element_name() }; let (optional, optional_span) = if self.at(Kind::Question) { let span = self.start_span(); @@ -308,7 +304,7 @@ impl<'a> ParserImpl<'a> { if optional { self.error(diagnostics::optional_accessor_property(optional_span)); } - self.parse_class_accessor_property( + Some(self.parse_class_accessor_property( span, key, computed, @@ -317,8 +313,7 @@ impl<'a> ParserImpl<'a> { r#override, definite, accessibility, - ) - .map(Some) + )) } else if self.at(Kind::LParen) || self.at(Kind::LAngle) || r#async || generator { if !computed { if let Some((name, span)) = key.prop_name() { @@ -352,12 +347,12 @@ impl<'a> ParserImpl<'a> { r#abstract, accessibility, optional, - )?; - Ok(Some(definition)) + ); + Some(definition) } else { // getter and setter has no ts type annotation if !kind.is_method() { - return Err(self.unexpected()); + return self.unexpected(); } if !computed { if let Some((name, span)) = key.prop_name() { @@ -381,16 +376,16 @@ impl<'a> ParserImpl<'a> { accessibility, optional, definite, - )?; - Ok(Some(definition)) + ); + Some(definition) } } - fn parse_class_element_name(&mut self) -> Result<(PropertyKey<'a>, bool)> { + fn parse_class_element_name(&mut self) -> (PropertyKey<'a>, bool) { match self.cur_kind() { Kind::PrivateIdentifier => { let private_ident = self.parse_private_identifier(); - Ok((PropertyKey::PrivateIdentifier(self.alloc(private_ident)), false)) + (PropertyKey::PrivateIdentifier(self.alloc(private_ident)), false) } _ => self.parse_property_name(), } @@ -409,7 +404,7 @@ impl<'a> ParserImpl<'a> { r#abstract: bool, accessibility: Option, optional: bool, - ) -> Result> { + ) -> ClassElement<'a> { let kind = if !r#static && !computed && key.prop_name().is_some_and(|(name, _)| name == "constructor") @@ -421,7 +416,7 @@ impl<'a> ParserImpl<'a> { let decorators = self.consume_decorators(); - let value = self.parse_method(r#async, generator)?; + let value = self.parse_method(r#async, generator); if kind == MethodDefinitionKind::Constructor { if let Some(this_param) = &value.this_param { @@ -444,7 +439,7 @@ impl<'a> ParserImpl<'a> { } else { MethodDefinitionType::MethodDefinition }; - Ok(self.ast.class_element_method_definition( + self.ast.class_element_method_definition( self.end_span(span), r#type, decorators, @@ -456,7 +451,7 @@ impl<'a> ParserImpl<'a> { r#override, optional, accessibility, - )) + ) } /// `FieldDefinition`[?Yield, ?Await] ; @@ -473,18 +468,18 @@ impl<'a> ParserImpl<'a> { accessibility: Option, optional: bool, definite: bool, - ) -> Result> { - let type_annotation = if self.is_ts { self.parse_ts_type_annotation()? } else { None }; + ) -> ClassElement<'a> { + let type_annotation = if self.is_ts { self.parse_ts_type_annotation() } else { None }; let decorators = self.consume_decorators(); - let value = if self.eat(Kind::Eq) { Some(self.parse_expr()?) } else { None }; - self.asi()?; + let value = if self.eat(Kind::Eq) { Some(self.parse_expr()) } else { None }; + self.asi(); let r#type = if r#abstract { PropertyDefinitionType::TSAbstractPropertyDefinition } else { PropertyDefinitionType::PropertyDefinition }; - Ok(self.ast.class_element_property_definition( + self.ast.class_element_property_definition( self.end_span(span), r#type, decorators, @@ -499,15 +494,15 @@ impl<'a> ParserImpl<'a> { readonly, type_annotation, accessibility, - )) + ) } /// `ClassStaticBlockStatementList` : /// `StatementList`[~Yield, +Await, ~Return] - fn parse_class_static_block(&mut self, span: u32) -> Result> { + fn parse_class_static_block(&mut self, span: u32) -> ClassElement<'a> { let block = - self.context(Context::Await, Context::Yield | Context::Return, Self::parse_block)?; - Ok(self.ast.class_element_static_block(self.end_span(span), block.unbox().body)) + self.context(Context::Await, Context::Yield | Context::Return, Self::parse_block); + self.ast.class_element_static_block(self.end_span(span), block.unbox().body) } /// @@ -521,18 +516,17 @@ impl<'a> ParserImpl<'a> { r#override: bool, definite: bool, accessibility: Option, - ) -> Result> { - let type_annotation = if self.is_ts { self.parse_ts_type_annotation()? } else { None }; - let value = - self.eat(Kind::Eq).then(|| self.parse_assignment_expression_or_higher()).transpose()?; - self.asi()?; + ) -> ClassElement<'a> { + let type_annotation = if self.is_ts { self.parse_ts_type_annotation() } else { None }; + let value = self.eat(Kind::Eq).then(|| self.parse_assignment_expression_or_higher()); + self.asi(); let r#type = if r#abstract { AccessorPropertyType::TSAbstractAccessorProperty } else { AccessorPropertyType::AccessorProperty }; let decorators = self.consume_decorators(); - Ok(self.ast.class_element_accessor_property( + self.ast.class_element_accessor_property( self.end_span(span), r#type, decorators, @@ -544,6 +538,6 @@ impl<'a> ParserImpl<'a> { definite, type_annotation, accessibility, - )) + ) } } diff --git a/crates/oxc_parser/src/js/declaration.rs b/crates/oxc_parser/src/js/declaration.rs index 5eb8cd6015bfc..8936c55be8170 100644 --- a/crates/oxc_parser/src/js/declaration.rs +++ b/crates/oxc_parser/src/js/declaration.rs @@ -1,6 +1,5 @@ use oxc_allocator::Box; use oxc_ast::{NONE, ast::*}; -use oxc_diagnostics::Result; use oxc_span::GetSpan; use super::VariableDeclarationParent; @@ -11,33 +10,33 @@ use crate::{ }; impl<'a> ParserImpl<'a> { - pub(crate) fn parse_let(&mut self, stmt_ctx: StatementContext) -> Result> { + pub(crate) fn parse_let(&mut self, stmt_ctx: StatementContext) -> Statement<'a> { let span = self.start_span(); let peeked = self.peek_kind(); // let = foo, let instanceof x, let + 1 if peeked.is_assignment_operator() || peeked.is_binary_operator() { - let expr = self.parse_assignment_expression_or_higher()?; + let expr = self.parse_assignment_expression_or_higher(); self.parse_expression_statement(span, expr) // let.a = 1, let()[a] = 1 } else if matches!(peeked, Kind::Dot | Kind::LParen) { - let expr = self.parse_expr()?; - Ok(self.ast.statement_expression(self.end_span(span), expr)) + let expr = self.parse_expr(); + self.ast.statement_expression(self.end_span(span), expr) // single statement let declaration: while (0) let } else if (stmt_ctx.is_single_statement() && peeked != Kind::LBrack) || peeked == Kind::Semicolon { - let expr = self.parse_identifier_expression()?; + let expr = self.parse_identifier_expression(); self.parse_expression_statement(span, expr) } else { self.parse_variable_statement(stmt_ctx) } } - pub(crate) fn parse_using_statement(&mut self) -> Result> { - let mut decl = self.parse_using_declaration(StatementContext::StatementList)?; - self.asi()?; + pub(crate) fn parse_using_statement(&mut self) -> Statement<'a> { + let mut decl = self.parse_using_declaration(StatementContext::StatementList); + self.asi(); decl.span = self.end_span(decl.span.start); - Ok(Statement::VariableDeclaration(self.alloc(decl))) + Statement::VariableDeclaration(self.alloc(decl)) } pub(crate) fn parse_variable_declaration( @@ -45,18 +44,18 @@ impl<'a> ParserImpl<'a> { start_span: u32, decl_parent: VariableDeclarationParent, modifiers: &Modifiers<'a>, - ) -> Result>> { + ) -> Box<'a, VariableDeclaration<'a>> { let kind = match self.cur_kind() { Kind::Var => VariableDeclarationKind::Var, Kind::Const => VariableDeclarationKind::Const, Kind::Let => VariableDeclarationKind::Let, - _ => return Err(self.unexpected()), + _ => return self.unexpected(), }; self.bump_any(); let mut declarations = self.ast.vec(); loop { - let declaration = self.parse_variable_declarator(decl_parent, kind)?; + let declaration = self.parse_variable_declarator(decl_parent, kind); declarations.push(declaration); if !self.eat(Kind::Comma) { break; @@ -64,7 +63,7 @@ impl<'a> ParserImpl<'a> { } if matches!(decl_parent, VariableDeclarationParent::Statement) { - self.asi()?; + self.asi(); } self.verify_modifiers( @@ -73,22 +72,22 @@ impl<'a> ParserImpl<'a> { diagnostics::modifier_cannot_be_used_here, ); - Ok(self.ast.alloc_variable_declaration( + self.ast.alloc_variable_declaration( self.end_span(start_span), kind, declarations, modifiers.contains_declare(), - )) + ) } fn parse_variable_declarator( &mut self, decl_parent: VariableDeclarationParent, kind: VariableDeclarationKind, - ) -> Result> { + ) -> VariableDeclarator<'a> { let span = self.start_span(); - let mut binding_kind = self.parse_binding_pattern_kind()?; + let mut binding_kind = self.parse_binding_pattern_kind(); let (id, definite) = if self.is_ts { // const x!: number = 1 @@ -102,7 +101,7 @@ impl<'a> ParserImpl<'a> { definite = true; } let optional = self.eat(Kind::Question); // not allowed, but checked in checker/typescript.rs - let type_annotation = self.parse_ts_type_annotation()?; + let type_annotation = self.parse_ts_type_annotation(); if let Some(type_annotation) = &type_annotation { Self::extend_binding_pattern_span_end(type_annotation.span.end, &mut binding_kind); } @@ -110,13 +109,12 @@ impl<'a> ParserImpl<'a> { } else { (self.ast.binding_pattern(binding_kind, NONE, false), false) }; - let init = - self.eat(Kind::Eq).then(|| self.parse_assignment_expression_or_higher()).transpose()?; + let init = self.eat(Kind::Eq).then(|| self.parse_assignment_expression_or_higher()); let decl = self.ast.variable_declarator(self.end_span(span), kind, id, init, definite); if decl_parent == VariableDeclarationParent::Statement { self.check_missing_initializer(&decl); } - Ok(decl) + decl } pub(crate) fn check_missing_initializer(&mut self, decl: &VariableDeclarator<'a>) { @@ -136,12 +134,12 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_using_declaration( &mut self, statement_ctx: StatementContext, - ) -> Result> { + ) -> VariableDeclaration<'a> { let span = self.start_span(); let is_await = self.eat(Kind::Await); - self.expect(Kind::Using)?; + self.expect(Kind::Using); // BindingList[?In, ?Yield, ?Await, ~Pattern] let mut declarations: oxc_allocator::Vec<'_, VariableDeclarator<'_>> = self.ast.vec(); @@ -153,7 +151,7 @@ impl<'a> ParserImpl<'a> { } else { VariableDeclarationKind::Using }, - )?; + ); match declaration.id.kind { BindingPatternKind::BindingIdentifier(_) => {} @@ -182,6 +180,6 @@ impl<'a> ParserImpl<'a> { } else { VariableDeclarationKind::Using }; - Ok(self.ast.variable_declaration(self.end_span(span), kind, declarations, false)) + self.ast.variable_declaration(self.end_span(span), kind, declarations, false) } } diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 2cfe37c9ed629..7cd533c330b50 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -1,7 +1,6 @@ use cow_utils::CowUtils; use oxc_allocator::{Box, TakeIn}; use oxc_ast::ast::*; -use oxc_diagnostics::Result; #[cfg(feature = "regular_expression")] use oxc_regular_expression::ast::Pattern; use oxc_span::{Atom, GetSpan, Span}; @@ -23,15 +22,15 @@ use crate::{ }; impl<'a> ParserImpl<'a> { - pub(crate) fn parse_paren_expression(&mut self) -> Result> { - self.expect(Kind::LParen)?; - let expression = self.parse_expr()?; - self.expect(Kind::RParen)?; - Ok(expression) + pub(crate) fn parse_paren_expression(&mut self) -> Expression<'a> { + self.expect(Kind::LParen); + let expression = self.parse_expr(); + self.expect(Kind::RParen); + expression } /// Section [Expression](https://tc39.es/ecma262/#sec-ecmascript-language-expressions) - pub(crate) fn parse_expr(&mut self) -> Result> { + pub(crate) fn parse_expr(&mut self) -> Expression<'a> { let span = self.start_span(); let has_decorator = self.ctx.has_decorator(); @@ -39,68 +38,68 @@ impl<'a> ParserImpl<'a> { self.ctx = self.ctx.and_decorator(false); } - let lhs = self.parse_assignment_expression_or_higher()?; + let lhs = self.parse_assignment_expression_or_higher(); if !self.at(Kind::Comma) { - return Ok(lhs); + return lhs; } - let expr = self.parse_sequence_expression(span, lhs)?; + let expr = self.parse_sequence_expression(span, lhs); if has_decorator { self.ctx = self.ctx.and_decorator(true); } - Ok(expr) + expr } /// `PrimaryExpression`: Identifier Reference - pub(crate) fn parse_identifier_expression(&mut self) -> Result> { - let ident = self.parse_identifier_reference()?; - Ok(Expression::Identifier(self.alloc(ident))) + pub(crate) fn parse_identifier_expression(&mut self) -> Expression<'a> { + let ident = self.parse_identifier_reference(); + Expression::Identifier(self.alloc(ident)) } - pub(crate) fn parse_identifier_reference(&mut self) -> Result> { + pub(crate) fn parse_identifier_reference(&mut self) -> IdentifierReference<'a> { // allow `await` and `yield`, let semantic analysis report error if !self.cur_kind().is_identifier_reference(false, false) { - return Err(self.unexpected()); + return self.unexpected(); } let (span, name) = self.parse_identifier_kind(Kind::Ident); self.check_identifier(span, &name); - Ok(self.ast.identifier_reference(span, name)) + self.ast.identifier_reference(span, name) } /// `BindingIdentifier` : Identifier - pub(crate) fn parse_binding_identifier(&mut self) -> Result> { + pub(crate) fn parse_binding_identifier(&mut self) -> BindingIdentifier<'a> { let cur = self.cur_kind(); if !cur.is_binding_identifier() { - return Err(if cur.is_reserved_keyword() { + return if cur.is_reserved_keyword() { let error = diagnostics::identifier_reserved_word(self.cur_token().span(), cur.to_str()); - self.set_fatal_error(error) + self.fatal_error(error) } else { self.unexpected() - }); + }; } let (span, name) = self.parse_identifier_kind(Kind::Ident); self.check_identifier(span, &name); - Ok(self.ast.binding_identifier(span, name)) + self.ast.binding_identifier(span, name) } - pub(crate) fn parse_label_identifier(&mut self) -> Result> { + pub(crate) fn parse_label_identifier(&mut self) -> LabelIdentifier<'a> { if !self.cur_kind().is_label_identifier(self.ctx.has_yield(), self.ctx.has_await()) { - return Err(self.unexpected()); + return self.unexpected(); } let (span, name) = self.parse_identifier_kind(Kind::Ident); self.check_identifier(span, &name); - Ok(self.ast.label_identifier(span, name)) + self.ast.label_identifier(span, name) } - pub(crate) fn parse_identifier_name(&mut self) -> Result> { + pub(crate) fn parse_identifier_name(&mut self) -> IdentifierName<'a> { if !self.cur_kind().is_identifier_name() { - return Err(self.unexpected()); + return self.unexpected(); } let (span, name) = self.parse_identifier_kind(Kind::Ident); - Ok(self.ast.identifier_name(span, name)) + self.ast.identifier_name(span, name) } /// Parse keyword kind as identifier @@ -154,11 +153,11 @@ impl<'a> ParserImpl<'a> { /// `RegularExpressionLiteral` /// `TemplateLiteral`[?Yield, ?Await, ~Tagged] /// `CoverParenthesizedExpressionAndArrowParameterList`[?Yield, ?Await] - fn parse_primary_expression(&mut self) -> Result> { + fn parse_primary_expression(&mut self) -> Expression<'a> { let span = self.start_span(); if self.at(Kind::At) { - self.eat_decorators()?; + self.eat_decorators(); } // FunctionExpression, GeneratorExpression @@ -173,23 +172,24 @@ impl<'a> ParserImpl<'a> { // ArrayLiteral Kind::LBrack => self.parse_array_expression(), // ObjectLiteral - Kind::LCurly => self.parse_object_expression().map(Expression::ObjectExpression), + Kind::LCurly => Expression::ObjectExpression(self.parse_object_expression()), // ClassExpression Kind::Class => self.parse_class_expression(), // This - Kind::This => Ok(self.parse_this_expression()), + Kind::This => self.parse_this_expression(), // TemplateLiteral Kind::NoSubstitutionTemplate | Kind::TemplateHead => { self.parse_template_literal_expression(false) } Kind::Percent => self.parse_v8_intrinsic_expression(), Kind::New => self.parse_new_expression(), - Kind::Super => Ok(self.parse_super()), + Kind::Super => self.parse_super(), Kind::Import => self.parse_import_meta_or_call(), Kind::LParen => self.parse_parenthesized_expression(span), - Kind::Slash | Kind::SlashEq => self - .parse_literal_regexp() - .map(|literal| Expression::RegExpLiteral(self.alloc(literal))), + Kind::Slash | Kind::SlashEq => { + let literal = self.parse_literal_regexp(); + Expression::RegExpLiteral(self.alloc(literal)) + } // Literal, RegularExpressionLiteral kind if kind.is_literal() => self.parse_literal_expression(), // JSXElement, JSXFragment @@ -198,8 +198,8 @@ impl<'a> ParserImpl<'a> { } } - fn parse_parenthesized_expression(&mut self, span: u32) -> Result> { - self.expect(Kind::LParen)?; + fn parse_parenthesized_expression(&mut self, span: u32) -> Expression<'a> { + self.expect(Kind::LParen); let expr_span = self.start_span(); let mut expressions = self.context(Context::In, Context::Decorator, |p| { p.parse_delimited_list( @@ -208,16 +208,16 @@ impl<'a> ParserImpl<'a> { /* trailing_separator */ false, Self::parse_assignment_expression_or_higher, ) - })?; + }); if expressions.is_empty() { - self.expect(Kind::RParen)?; + self.expect(Kind::RParen); let error = diagnostics::empty_parenthesized_expression(self.end_span(span)); - return Err(self.set_fatal_error(error)); + return self.fatal_error(error); } let expr_span = self.end_span(expr_span); - self.expect(Kind::RParen)?; + self.expect(Kind::RParen); // ParenthesizedExpression is from acorn --preserveParens let expression = if expressions.len() == 1 { @@ -226,11 +226,11 @@ impl<'a> ParserImpl<'a> { self.ast.expression_sequence(expr_span, expressions) }; - Ok(if self.options.preserve_parens { + if self.options.preserve_parens { self.ast.expression_parenthesized(self.end_span(span), expression) } else { expression - }) + } } /// Section 13.2.2 This Expression @@ -242,40 +242,42 @@ impl<'a> ParserImpl<'a> { /// [Literal Expression](https://tc39.es/ecma262/#prod-Literal) /// parses string | true | false | null | number - pub(crate) fn parse_literal_expression(&mut self) -> Result> { + pub(crate) fn parse_literal_expression(&mut self) -> Expression<'a> { match self.cur_kind() { - Kind::Str => self - .parse_literal_string() - .map(|literal| Expression::StringLiteral(self.alloc(literal))), - Kind::True | Kind::False => self - .parse_literal_boolean() - .map(|literal| Expression::BooleanLiteral(self.alloc(literal))), + Kind::Str => { + let lit = self.parse_literal_string(); + Expression::StringLiteral(self.alloc(lit)) + } + Kind::True | Kind::False => { + let lit = self.parse_literal_boolean(); + Expression::BooleanLiteral(self.alloc(lit)) + } Kind::Null => { - let literal = self.parse_literal_null(); - Ok(Expression::NullLiteral(self.alloc(literal))) + let lit = self.parse_literal_null(); + Expression::NullLiteral(self.alloc(lit)) } kind if kind.is_number() => { if self.cur_src().ends_with('n') { - self.parse_literal_bigint() - .map(|literal| Expression::BigIntLiteral(self.alloc(literal))) + let lit = self.parse_literal_bigint(); + Expression::BigIntLiteral(self.alloc(lit)) } else { - self.parse_literal_number() - .map(|literal| Expression::NumericLiteral(self.alloc(literal))) + let lit = self.parse_literal_number(); + Expression::NumericLiteral(self.alloc(lit)) } } - _ => Err(self.unexpected()), + _ => self.unexpected(), } } - pub(crate) fn parse_literal_boolean(&mut self) -> Result { + pub(crate) fn parse_literal_boolean(&mut self) -> BooleanLiteral { let span = self.start_span(); let value = match self.cur_kind() { Kind::True => true, Kind::False => false, - _ => return Err(self.unexpected()), + _ => return self.unexpected(), }; self.bump_any(); - Ok(self.ast.boolean_literal(self.end_span(span), value)) + self.ast.boolean_literal(self.end_span(span), value) } pub(crate) fn parse_literal_null(&mut self) -> NullLiteral { @@ -284,7 +286,7 @@ impl<'a> ParserImpl<'a> { self.ast.null_literal(self.end_span(span)) } - pub(crate) fn parse_literal_number(&mut self) -> Result> { + pub(crate) fn parse_literal_number(&mut self) -> NumericLiteral<'a> { let span = self.start_span(); let token = self.cur_token(); let src = self.cur_src(); @@ -296,8 +298,11 @@ impl<'a> ParserImpl<'a> { parse_float(src, token.has_separator()) } _ => unreachable!(), - } - .map_err(|err| diagnostics::invalid_number(err, token.span()))?; + }; + let value = value.unwrap_or_else(|err| { + self.set_fatal_error(diagnostics::invalid_number(err, token.span())); + 0.0 // Dummy value + }); let base = match token.kind { Kind::Decimal => NumberBase::Decimal, Kind::Float => NumberBase::Float, @@ -311,34 +316,39 @@ impl<'a> ParserImpl<'a> { NumberBase::Float } } - _ => return Err(self.unexpected()), + _ => return self.unexpected(), }; self.bump_any(); - Ok(self.ast.numeric_literal(self.end_span(span), value, Some(Atom::from(src)), base)) + self.ast.numeric_literal(self.end_span(span), value, Some(Atom::from(src)), base) } - pub(crate) fn parse_literal_bigint(&mut self) -> Result> { + pub(crate) fn parse_literal_bigint(&mut self) -> BigIntLiteral<'a> { let span = self.start_span(); let base = match self.cur_kind() { Kind::Decimal => BigintBase::Decimal, Kind::Binary => BigintBase::Binary, Kind::Octal => BigintBase::Octal, Kind::Hex => BigintBase::Hex, - _ => return Err(self.unexpected()), + _ => return self.unexpected(), }; let token = self.cur_token(); let raw = self.cur_src(); let src = raw.strip_suffix('n').unwrap(); let _value = parse_big_int(src, token.kind, token.has_separator()) - .map_err(|err| diagnostics::invalid_number(err, token.span()))?; + .map_err(|err| diagnostics::invalid_number(err, token.span())); self.bump_any(); - Ok(self.ast.big_int_literal(self.end_span(span), raw, base)) + self.ast.big_int_literal(self.end_span(span), raw, base) } - pub(crate) fn parse_literal_regexp(&mut self) -> Result> { + pub(crate) fn parse_literal_regexp(&mut self) -> RegExpLiteral<'a> { let span = self.start_span(); // split out pattern - let (pattern_end, flags, flags_error) = self.read_regex()?; + let (pattern_end, flags, flags_error) = match self.read_regex() { + Ok(res) => res, + Err(error) => { + return self.fatal_error(error); + } + }; let pattern_start = self.cur_token().start + 1; // +1 to exclude left `/` let pattern_text = &self.source_text[pattern_start as usize..pattern_end as usize]; let flags_start = pattern_end + 1; // +1 to include right `/` @@ -370,11 +380,11 @@ impl<'a> ParserImpl<'a> { RegExpPattern::Raw(pattern_text) }; - Ok(self.ast.reg_exp_literal( + self.ast.reg_exp_literal( self.end_span(span), RegExp { pattern, flags }, Some(Atom::from(raw)), - )) + ) } #[cfg(feature = "regular_expression")] @@ -402,9 +412,9 @@ impl<'a> ParserImpl<'a> { } } - pub(crate) fn parse_literal_string(&mut self) -> Result> { + pub(crate) fn parse_literal_string(&mut self) -> StringLiteral<'a> { if !self.at(Kind::Str) { - return Err(self.unexpected()); + return self.unexpected(); } let value = self.cur_string(); let span = self.start_span(); @@ -416,7 +426,7 @@ impl<'a> ParserImpl<'a> { let raw = Atom::from(unsafe { self.source_text.get_unchecked(span.start as usize..span.end as usize) }); - Ok(self.ast.string_literal_with_lone_surrogates(span, value, Some(raw), lone_surrogates)) + self.ast.string_literal_with_lone_surrogates(span, value, Some(raw), lone_surrogates) } /// Section [Array Expression](https://tc39.es/ecma262/#prod-ArrayLiteral) @@ -424,9 +434,9 @@ impl<'a> ParserImpl<'a> { /// [ Elision opt ] /// [ `ElementList`[?Yield, ?Await] ] /// [ `ElementList`[?Yield, ?Await] , Elisionopt ] - pub(crate) fn parse_array_expression(&mut self) -> Result> { + pub(crate) fn parse_array_expression(&mut self) -> Expression<'a> { let span = self.start_span(); - self.expect(Kind::LBrack)?; + self.expect(Kind::LBrack); let elements = self.context(Context::In, Context::empty(), |p| { p.parse_delimited_list( Kind::RBrack, @@ -434,21 +444,21 @@ impl<'a> ParserImpl<'a> { /* trailing_separator */ false, Self::parse_array_expression_element, ) - })?; + }); if self.at(Kind::Comma) { let comma_span = self.start_span(); self.bump_any(); self.state.trailing_commas.insert(span, self.end_span(comma_span)); } - self.expect(Kind::RBrack)?; - Ok(self.ast.expression_array(self.end_span(span), elements)) + self.expect(Kind::RBrack); + self.ast.expression_array(self.end_span(span), elements) } - fn parse_array_expression_element(&mut self) -> Result> { + fn parse_array_expression_element(&mut self) -> ArrayExpressionElement<'a> { match self.cur_kind() { - Kind::Comma => Ok(self.parse_elision()), - Kind::Dot3 => self.parse_spread_element().map(ArrayExpressionElement::SpreadElement), - _ => self.parse_assignment_expression_or_higher().map(ArrayExpressionElement::from), + Kind::Comma => self.parse_elision(), + Kind::Dot3 => ArrayExpressionElement::SpreadElement(self.parse_spread_element()), + _ => ArrayExpressionElement::from(self.parse_assignment_expression_or_higher()), } } @@ -463,7 +473,7 @@ impl<'a> ParserImpl<'a> { /// `TemplateLiteral`[Yield, Await, Tagged] : /// `NoSubstitutionTemplate` /// `SubstitutionTemplate`[?Yield, ?Await, ?Tagged] - pub(crate) fn parse_template_literal(&mut self, tagged: bool) -> Result> { + pub(crate) fn parse_template_literal(&mut self, tagged: bool) -> TemplateLiteral<'a> { let span = self.start_span(); let mut expressions = self.ast.vec(); let mut quasis = self.ast.vec(); @@ -474,10 +484,10 @@ impl<'a> ParserImpl<'a> { Kind::TemplateHead => { quasis.push(self.parse_template_element(tagged)); // TemplateHead Expression[+In, ?Yield, ?Await] - let expr = self.context(Context::In, Context::empty(), Self::parse_expr)?; + let expr = self.context(Context::In, Context::empty(), Self::parse_expr); expressions.push(expr); self.re_lex_template_substitution_tail(); - loop { + while self.fatal_error.is_none() { match self.cur_kind() { Kind::TemplateTail => { quasis.push(self.parse_template_element(tagged)); @@ -486,11 +496,14 @@ impl<'a> ParserImpl<'a> { Kind::TemplateMiddle => { quasis.push(self.parse_template_element(tagged)); } - _ if self.has_fatal_error() => self.expect(Kind::TemplateTail)?, + Kind::Eof => { + self.expect(Kind::TemplateTail); + break; + } _ => { // TemplateMiddle Expression[+In, ?Yield, ?Await] let expr = - self.context(Context::In, Context::empty(), Self::parse_expr)?; + self.context(Context::In, Context::empty(), Self::parse_expr); expressions.push(expr); self.re_lex_template_substitution_tail(); } @@ -499,15 +512,12 @@ impl<'a> ParserImpl<'a> { } _ => unreachable!("parse_template_literal"), } - Ok(self.ast.template_literal(self.end_span(span), quasis, expressions)) + self.ast.template_literal(self.end_span(span), quasis, expressions) } - pub(crate) fn parse_template_literal_expression( - &mut self, - tagged: bool, - ) -> Result> { - self.parse_template_literal(tagged) - .map(|template_literal| Expression::TemplateLiteral(self.alloc(template_literal))) + pub(crate) fn parse_template_literal_expression(&mut self, tagged: bool) -> Expression<'a> { + let template_lit = self.parse_template_literal(tagged); + Expression::TemplateLiteral(self.alloc(template_lit)) } fn parse_tagged_template( @@ -516,8 +526,8 @@ impl<'a> ParserImpl<'a> { lhs: Expression<'a>, in_optional_chain: bool, type_parameters: Option>>, - ) -> Result> { - let quasi = self.parse_template_literal(true)?; + ) -> Expression<'a> { + let quasi = self.parse_template_literal(true); let span = self.end_span(span); // OptionalChain : // ?. TemplateLiteral @@ -527,7 +537,7 @@ impl<'a> ParserImpl<'a> { if in_optional_chain { self.error(diagnostics::optional_chain_tagged_template(quasi.span)); } - Ok(self.ast.expression_tagged_template(span, lhs, quasi, type_parameters)) + self.ast.expression_tagged_template(span, lhs, quasi, type_parameters) } pub(crate) fn parse_template_element(&mut self, tagged: bool) -> TemplateElement<'a> { @@ -572,7 +582,7 @@ impl<'a> ParserImpl<'a> { } /// Section 13.3 ImportCall or ImportMeta - fn parse_import_meta_or_call(&mut self) -> Result> { + fn parse_import_meta_or_call(&mut self) -> Expression<'a> { let span = self.start_span(); let meta = self.parse_keyword_identifier(Kind::Import); match self.cur_kind() { @@ -584,7 +594,7 @@ impl<'a> ParserImpl<'a> { let property = self.parse_keyword_identifier(Kind::Meta); let span = self.end_span(span); self.module_record_builder.visit_import_meta(span); - Ok(self.ast.expression_meta_property(span, meta, property)) + self.ast.expression_meta_property(span, meta, property) } // `import.source(expr)` Kind::Source => { @@ -598,27 +608,27 @@ impl<'a> ParserImpl<'a> { } _ => { self.bump_any(); - Err(diagnostics::import_meta(self.end_span(span))) + self.fatal_error(diagnostics::import_meta(self.end_span(span))) } } } Kind::LParen => self.parse_import_expression(span, None), - _ => Err(self.unexpected()), + _ => self.unexpected(), } } /// V8 Runtime calls. /// See: [runtime.h](https://github.com/v8/v8/blob/5fe0aa3bc79c0a9d3ad546b79211f07105f09585/src/runtime/runtime.h#L43) - pub(crate) fn parse_v8_intrinsic_expression(&mut self) -> Result> { + pub(crate) fn parse_v8_intrinsic_expression(&mut self) -> Expression<'a> { if !self.options.allow_v8_intrinsics { - return Err(self.unexpected()); + return self.unexpected(); } let span = self.start_span(); - self.expect(Kind::Percent)?; - let name = self.parse_identifier_name()?; + self.expect(Kind::Percent); + let name = self.parse_identifier_name(); - self.expect(Kind::LParen)?; + self.expect(Kind::LParen); let arguments = self.context(Context::In, Context::Decorator, |p| { p.parse_delimited_list( Kind::RParen, @@ -626,28 +636,28 @@ impl<'a> ParserImpl<'a> { /* trailing_separator */ true, Self::parse_v8_intrinsic_argument, ) - })?; - self.expect(Kind::RParen)?; - Ok(self.ast.expression_v_8_intrinsic(self.end_span(span), name, arguments)) + }); + self.expect(Kind::RParen); + self.ast.expression_v_8_intrinsic(self.end_span(span), name, arguments) } - fn parse_v8_intrinsic_argument(&mut self) -> Result> { + fn parse_v8_intrinsic_argument(&mut self) -> Argument<'a> { if self.at(Kind::Dot3) { self.error(diagnostics::v8_intrinsic_spread_elem(self.cur_token().span())); - self.parse_spread_element().map(Argument::SpreadElement) + Argument::SpreadElement(self.parse_spread_element()) } else { - self.parse_assignment_expression_or_higher().map(Argument::from) + Argument::from(self.parse_assignment_expression_or_higher()) } } /// Section 13.3 Left-Hand-Side Expression - pub(crate) fn parse_lhs_expression_or_higher(&mut self) -> Result> { + pub(crate) fn parse_lhs_expression_or_higher(&mut self) -> Expression<'a> { let span = self.start_span(); let mut in_optional_chain = false; - let lhs = self.parse_member_expression_or_higher(&mut in_optional_chain)?; - let lhs = self.parse_call_expression_rest(span, lhs, &mut in_optional_chain)?; + let lhs = self.parse_member_expression_or_higher(&mut in_optional_chain); + let lhs = self.parse_call_expression_rest(span, lhs, &mut in_optional_chain); if !in_optional_chain { - return Ok(lhs); + return lhs; } // Add `ChainExpression` to `a?.c?.b`; if let Expression::TSInstantiationExpression(mut expr) = lhs { @@ -655,10 +665,10 @@ impl<'a> ParserImpl<'a> { expr.expression.span(), expr.expression.take_in(self.ast.allocator), ); - Ok(Expression::TSInstantiationExpression(expr)) + Expression::TSInstantiationExpression(expr) } else { let span = self.end_span(span); - Ok(self.map_to_chain_expression(span, lhs)) + self.map_to_chain_expression(span, lhs) } } @@ -682,9 +692,9 @@ impl<'a> ParserImpl<'a> { fn parse_member_expression_or_higher( &mut self, in_optional_chain: &mut bool, - ) -> Result> { + ) -> Expression<'a> { let span = self.start_span(); - let lhs = self.parse_primary_expression()?; + let lhs = self.parse_primary_expression(); self.parse_member_expression_rest(span, lhs, in_optional_chain) } @@ -713,23 +723,23 @@ impl<'a> ParserImpl<'a> { lhs_span: u32, lhs: Expression<'a>, in_optional_chain: &mut bool, - ) -> Result> { + ) -> Expression<'a> { let mut lhs = lhs; loop { lhs = match self.cur_kind() { - Kind::Dot => self.parse_static_member_expression(lhs_span, lhs, false)?, + Kind::Dot => self.parse_static_member_expression(lhs_span, lhs, false), Kind::QuestionDot => { *in_optional_chain = true; match self.peek_kind() { Kind::LBrack if !self.ctx.has_decorator() => { self.bump_any(); // bump `?.` - self.parse_computed_member_expression(lhs_span, lhs, true)? + self.parse_computed_member_expression(lhs_span, lhs, true) } Kind::PrivateIdentifier => { - self.parse_static_member_expression(lhs_span, lhs, true)? + self.parse_static_member_expression(lhs_span, lhs, true) } kind if kind.is_identifier_name() => { - self.parse_static_member_expression(lhs_span, lhs, true)? + self.parse_static_member_expression(lhs_span, lhs, true) } Kind::Bang | Kind::LAngle @@ -739,7 +749,7 @@ impl<'a> ParserImpl<'a> { | Kind::TemplateHead | Kind::LBrack => break, _ => { - return Err(self.unexpected()); + return self.unexpected(); } } } @@ -747,7 +757,7 @@ impl<'a> ParserImpl<'a> { // class C { @dec ["1"]() { } } // ^ Kind::LBrack if !self.ctx.has_decorator() => { - self.parse_computed_member_expression(lhs_span, lhs, false)? + self.parse_computed_member_expression(lhs_span, lhs, false) } Kind::Bang if !self.cur_token().is_on_new_line && self.is_ts => { self.bump_any(); @@ -761,7 +771,7 @@ impl<'a> ParserImpl<'a> { } else { (lhs, None) }; - 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 => { if let Some(Some(arguments)) = @@ -779,7 +789,7 @@ impl<'a> ParserImpl<'a> { _ => break, }; } - Ok(lhs) + lhs } /// Section 13.3 `MemberExpression` @@ -789,21 +799,20 @@ impl<'a> ParserImpl<'a> { lhs_span: u32, lhs: Expression<'a>, optional: bool, - ) -> Result> { + ) -> Expression<'a> { self.bump_any(); // advance `.` or `?.` - if self.cur_kind() == Kind::PrivateIdentifier { + Expression::from(if self.cur_kind() == Kind::PrivateIdentifier { let private_ident = self.parse_private_identifier(); - Ok(self.ast.member_expression_private_field_expression( + self.ast.member_expression_private_field_expression( self.end_span(lhs_span), lhs, private_ident, optional, - )) + ) } else { - let ident = self.parse_identifier_name()?; - Ok(self.ast.member_expression_static(self.end_span(lhs_span), lhs, ident, optional)) - } - .map(Expression::from) + let ident = self.parse_identifier_name(); + self.ast.member_expression_static(self.end_span(lhs_span), lhs, ident, optional) + }) } /// Section 13.3 `MemberExpression` @@ -814,34 +823,31 @@ impl<'a> ParserImpl<'a> { lhs_span: u32, lhs: Expression<'a>, optional: bool, - ) -> Result> { + ) -> Expression<'a> { self.bump_any(); // advance `[` - let property = self.context(Context::In, Context::empty(), Self::parse_expr)?; - self.expect(Kind::RBrack)?; - Ok(self - .ast - .member_expression_computed(self.end_span(lhs_span), lhs, property, optional) - .into()) + let property = self.context(Context::In, Context::empty(), Self::parse_expr); + self.expect(Kind::RBrack); + self.ast.member_expression_computed(self.end_span(lhs_span), lhs, property, optional).into() } /// [NewExpression](https://tc39.es/ecma262/#sec-new-operator) - fn parse_new_expression(&mut self) -> Result> { + fn parse_new_expression(&mut self) -> Expression<'a> { let span = self.start_span(); let identifier = self.parse_keyword_identifier(Kind::New); if self.eat(Kind::Dot) { return if self.at(Kind::Target) { let property = self.parse_keyword_identifier(Kind::Target); - Ok(self.ast.expression_meta_property(self.end_span(span), identifier, property)) + self.ast.expression_meta_property(self.end_span(span), identifier, property) } else { self.bump_any(); - Err(diagnostics::new_target(self.end_span(span))) + self.fatal_error(diagnostics::new_target(self.end_span(span))) }; } let rhs_span = self.start_span(); let mut optional = false; - let mut callee = self.parse_member_expression_or_higher(&mut optional)?; + let mut callee = self.parse_member_expression_or_higher(&mut optional); let mut type_arguments = None; if let Expression::TSInstantiationExpression(instantiation_expr) = callee { @@ -861,8 +867,8 @@ impl<'a> ParserImpl<'a> { /* trailing_separator */ true, Self::parse_call_argument, ) - })?; - self.expect(Kind::RParen)?; + }); + self.expect(Kind::RParen); call_arguments } else { self.ast.vec() @@ -878,7 +884,7 @@ impl<'a> ParserImpl<'a> { self.error(diagnostics::new_optional_chain(span)); } - Ok(self.ast.expression_new(span, callee, arguments, type_arguments)) + self.ast.expression_new(span, callee, arguments, type_arguments) } /// Section 13.3 Call Expression @@ -887,11 +893,11 @@ impl<'a> ParserImpl<'a> { lhs_span: u32, lhs: Expression<'a>, in_optional_chain: &mut bool, - ) -> Result> { + ) -> Expression<'a> { let mut lhs = lhs; - loop { + while self.fatal_error.is_none() { let mut type_arguments = None; - lhs = self.parse_member_expression_rest(lhs_span, lhs, in_optional_chain)?; + lhs = self.parse_member_expression_rest(lhs_span, lhs, in_optional_chain); let optional_call = self.eat(Kind::QuestionDot); *in_optional_chain = if optional_call { true } else { *in_optional_chain }; @@ -900,8 +906,7 @@ impl<'a> ParserImpl<'a> { type_arguments = Some(args); } if self.cur_kind().is_template_start_of_tagged_template() { - lhs = - self.parse_tagged_template(lhs_span, lhs, optional_call, type_arguments)?; + lhs = self.parse_tagged_template(lhs_span, lhs, optional_call, type_arguments); continue; } } @@ -916,13 +921,13 @@ impl<'a> ParserImpl<'a> { } lhs = - self.parse_call_arguments(lhs_span, lhs, optional_call, type_arguments.take())?; + self.parse_call_arguments(lhs_span, lhs, optional_call, type_arguments.take()); continue; } break; } - Ok(lhs) + lhs } fn parse_call_arguments( @@ -931,10 +936,10 @@ impl<'a> ParserImpl<'a> { lhs: Expression<'a>, optional: bool, type_parameters: Option>>, - ) -> Result> { + ) -> Expression<'a> { // ArgumentList[Yield, Await] : // AssignmentExpression[+In, ?Yield, ?Await] - self.expect(Kind::LParen)?; + self.expect(Kind::LParen); let call_arguments = self.context(Context::In, Context::Decorator, |p| { p.parse_delimited_list( Kind::RParen, @@ -942,40 +947,35 @@ impl<'a> ParserImpl<'a> { /* trailing_separator */ true, Self::parse_call_argument, ) - })?; - self.expect(Kind::RParen)?; - Ok(self.ast.expression_call( + }); + self.expect(Kind::RParen); + self.ast.expression_call( self.end_span(lhs_span), lhs, type_parameters, call_arguments, optional, - )) + ) } - fn parse_call_argument(&mut self) -> Result> { + fn parse_call_argument(&mut self) -> Argument<'a> { if self.at(Kind::Dot3) { - self.parse_spread_element().map(Argument::SpreadElement) + Argument::SpreadElement(self.parse_spread_element()) } else { - self.parse_assignment_expression_or_higher().map(Argument::from) + Argument::from(self.parse_assignment_expression_or_higher()) } } /// Section 13.4 Update Expression - fn parse_update_expression(&mut self, lhs_span: u32) -> Result> { + fn parse_update_expression(&mut self, lhs_span: u32) -> Expression<'a> { let kind = self.cur_kind(); // ++ -- prefix update expressions if kind.is_update_operator() { let operator = map_update_operator(kind); self.bump_any(); - let argument = self.parse_unary_expression_or_higher(lhs_span)?; - let argument = SimpleAssignmentTarget::cover(argument, self)?; - return Ok(self.ast.expression_update( - self.end_span(lhs_span), - operator, - true, - argument, - )); + let argument = self.parse_unary_expression_or_higher(lhs_span); + let argument = SimpleAssignmentTarget::cover(argument, self); + return self.ast.expression_update(self.end_span(lhs_span), operator, true, argument); } if self.source_type.is_jsx() @@ -986,22 +986,19 @@ impl<'a> ParserImpl<'a> { } let span = self.start_span(); - let lhs = self.parse_lhs_expression_or_higher()?; + let lhs = self.parse_lhs_expression_or_higher(); // ++ -- postfix update expressions if self.cur_kind().is_update_operator() && !self.cur_token().is_on_new_line { let operator = map_update_operator(self.cur_kind()); self.bump_any(); - let lhs = SimpleAssignmentTarget::cover(lhs, self)?; - return Ok(self.ast.expression_update(self.end_span(span), operator, false, lhs)); + let lhs = SimpleAssignmentTarget::cover(lhs, self); + return self.ast.expression_update(self.end_span(span), operator, false, lhs); } - Ok(lhs) + lhs } /// Section 13.5 Unary Expression - pub(crate) fn parse_unary_expression_or_higher( - &mut self, - lhs_span: u32, - ) -> Result> { + pub(crate) fn parse_unary_expression_or_higher(&mut self, lhs_span: u32) -> Expression<'a> { // ++ -- prefix update expressions if self.is_update_expression() { return self.parse_update_expression(lhs_span); @@ -1009,10 +1006,7 @@ impl<'a> ParserImpl<'a> { self.parse_simple_unary_expression(lhs_span) } - pub(crate) fn parse_simple_unary_expression( - &mut self, - lhs_span: u32, - ) -> Result> { + pub(crate) fn parse_simple_unary_expression(&mut self, lhs_span: u32) -> Expression<'a> { match self.cur_kind() { kind if kind.is_unary_operator() => self.parse_unary_expression(), Kind::LAngle => { @@ -1022,43 +1016,43 @@ impl<'a> ParserImpl<'a> { if self.is_ts { return self.parse_ts_type_assertion(); } - Err(self.unexpected()) + self.unexpected() } Kind::Await if self.is_await_expression() => self.parse_await_expression(lhs_span), _ => self.parse_update_expression(lhs_span), } } - fn parse_unary_expression(&mut self) -> Result> { + fn parse_unary_expression(&mut self) -> Expression<'a> { let span = self.start_span(); let operator = map_unary_operator(self.cur_kind()); self.bump_any(); let has_pure_comment = self.lexer.trivia_builder.previous_token_has_pure_comment(); - let mut argument = self.parse_simple_unary_expression(self.start_span())?; + let mut argument = self.parse_simple_unary_expression(self.start_span()); if has_pure_comment { Self::set_pure_on_call_or_new_expr(&mut argument); } - Ok(self.ast.expression_unary(self.end_span(span), operator, argument)) + self.ast.expression_unary(self.end_span(span), operator, argument) } pub(crate) fn parse_binary_expression_or_higher( &mut self, lhs_precedence: Precedence, - ) -> Result> { + ) -> Expression<'a> { let lhs_span = self.start_span(); let lhs = if self.ctx.has_in() && self.at(Kind::PrivateIdentifier) { let left = self.parse_private_identifier(); - self.expect(Kind::In)?; - let right = self.parse_binary_expression_or_higher(Precedence::Lowest)?; + self.expect(Kind::In); + let right = self.parse_binary_expression_or_higher(Precedence::Lowest); if let Expression::PrivateInExpression(private_in_expr) = right { let error = diagnostics::private_in_private(private_in_expr.span); - return Err(self.set_fatal_error(error)); + return self.fatal_error(error); } self.ast.expression_private_in(self.end_span(lhs_span), left, right) } else { let has_pure_comment = self.lexer.trivia_builder.previous_token_has_pure_comment(); - let mut expr = self.parse_unary_expression_or_higher(lhs_span)?; + let mut expr = self.parse_unary_expression_or_higher(lhs_span); if has_pure_comment { Self::set_pure_on_call_or_new_expr(&mut expr); } @@ -1074,7 +1068,7 @@ impl<'a> ParserImpl<'a> { lhs_span: u32, lhs: Expression<'a>, min_precedence: Precedence, - ) -> Result> { + ) -> Expression<'a> { // Pratt Parsing Algorithm // let mut lhs = lhs; @@ -1107,7 +1101,7 @@ impl<'a> ParserImpl<'a> { break; } self.bump_any(); - let type_annotation = self.parse_ts_type()?; + let type_annotation = self.parse_ts_type(); let span = self.end_span(lhs_span); lhs = if kind == Kind::As { self.ast.expression_ts_as(span, lhs, type_annotation) @@ -1118,7 +1112,7 @@ impl<'a> ParserImpl<'a> { } self.bump_any(); // bump operator - let rhs = self.parse_binary_expression_or_higher(left_precedence)?; + let rhs = self.parse_binary_expression_or_higher(left_precedence); lhs = if kind.is_logical_operator() { self.ast.expression_logical( @@ -1139,7 +1133,7 @@ impl<'a> ParserImpl<'a> { }; } - Ok(lhs) + lhs } /// Section 13.14 Conditional Expression @@ -1151,23 +1145,23 @@ impl<'a> ParserImpl<'a> { lhs_span: u32, lhs: Expression<'a>, allow_return_type_in_arrow_function: bool, - ) -> Result> { + ) -> Expression<'a> { if !self.eat(Kind::Question) { - return Ok(lhs); + return lhs; } let consequent = self.context(Context::In, Context::empty(), |p| { p.parse_assignment_expression_or_higher_impl( /* allow_return_type_in_arrow_function */ false, ) - })?; - self.expect(Kind::Colon)?; + }); + self.expect(Kind::Colon); let alternate = - self.parse_assignment_expression_or_higher_impl(allow_return_type_in_arrow_function)?; - Ok(self.ast.expression_conditional(self.end_span(lhs_span), lhs, consequent, alternate)) + self.parse_assignment_expression_or_higher_impl(allow_return_type_in_arrow_function); + self.ast.expression_conditional(self.end_span(lhs_span), lhs, consequent, alternate) } /// `AssignmentExpression`[In, Yield, Await] : - pub(crate) fn parse_assignment_expression_or_higher(&mut self) -> Result> { + pub(crate) fn parse_assignment_expression_or_higher(&mut self) -> Expression<'a> { self.parse_assignment_expression_or_higher_impl( /* allow_return_type_in_arrow_function */ true, ) @@ -1176,7 +1170,7 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_assignment_expression_or_higher_impl( &mut self, allow_return_type_in_arrow_function: bool, - ) -> Result> { + ) -> Expression<'a> { let has_no_side_effects_comment = self.lexer.trivia_builder.previous_token_has_no_side_effects_comment(); let has_pure_comment = self.lexer.trivia_builder.previous_token_has_pure_comment(); @@ -1185,30 +1179,30 @@ impl<'a> ParserImpl<'a> { return self.parse_yield_expression(); } // `() => {}`, `(x) => {}` - if let Some(mut arrow_expr) = self.try_parse_parenthesized_arrow_function_expression( - allow_return_type_in_arrow_function, - )? { + if let Some(mut arrow_expr) = self + .try_parse_parenthesized_arrow_function_expression(allow_return_type_in_arrow_function) + { if has_no_side_effects_comment { if let Expression::ArrowFunctionExpression(func) = &mut arrow_expr { func.pure = true; } } - return Ok(arrow_expr); + return arrow_expr; } // `async x => {}` if let Some(mut arrow_expr) = self - .try_parse_async_simple_arrow_function_expression(allow_return_type_in_arrow_function)? + .try_parse_async_simple_arrow_function_expression(allow_return_type_in_arrow_function) { if has_no_side_effects_comment { if let Expression::ArrowFunctionExpression(func) = &mut arrow_expr { func.pure = true; } } - return Ok(arrow_expr); + return arrow_expr; } let span = self.start_span(); - let lhs = self.parse_binary_expression_or_higher(Precedence::Comma)?; + let lhs = self.parse_binary_expression_or_higher(Precedence::Comma); let kind = self.cur_kind(); // `x => {}` @@ -1218,13 +1212,13 @@ impl<'a> ParserImpl<'a> { lhs, /* async */ false, allow_return_type_in_arrow_function, - )?; + ); if has_no_side_effects_comment { if let Expression::ArrowFunctionExpression(func) = &mut arrow_expr { func.pure = true; } } - return Ok(arrow_expr); + return arrow_expr; } if kind.is_assignment_operator() { @@ -1236,7 +1230,7 @@ impl<'a> ParserImpl<'a> { } let mut expr = - self.parse_conditional_expression_rest(span, lhs, allow_return_type_in_arrow_function)?; + self.parse_conditional_expression_rest(span, lhs, allow_return_type_in_arrow_function); if has_pure_comment { Self::set_pure_on_call_or_new_expr(&mut expr); @@ -1246,7 +1240,7 @@ impl<'a> ParserImpl<'a> { Self::set_pure_on_function_expr(&mut expr); } - Ok(expr) + expr } fn set_pure_on_call_or_new_expr(expr: &mut Expression<'a>) { @@ -1292,7 +1286,7 @@ impl<'a> ParserImpl<'a> { span: u32, lhs: Expression<'a>, allow_return_type_in_arrow_function: bool, - ) -> Result> { + ) -> Expression<'a> { let operator = map_assignment_operator(self.cur_kind()); // 13.15.5 Destructuring Assignment // LeftHandSideExpression = AssignmentExpression @@ -1300,11 +1294,11 @@ impl<'a> ParserImpl<'a> { // AssignmentPattern[Yield, Await] : // ObjectAssignmentPattern // ArrayAssignmentPattern - let left = AssignmentTarget::cover(lhs, self)?; + let left = AssignmentTarget::cover(lhs, self); self.bump_any(); let right = - self.parse_assignment_expression_or_higher_impl(allow_return_type_in_arrow_function)?; - Ok(self.ast.expression_assignment(self.end_span(span), operator, left, right)) + self.parse_assignment_expression_or_higher_impl(allow_return_type_in_arrow_function); + self.ast.expression_assignment(self.end_span(span), operator, left, right) } /// Section 13.16 Sequence Expression @@ -1312,18 +1306,18 @@ impl<'a> ParserImpl<'a> { &mut self, span: u32, first_expression: Expression<'a>, - ) -> Result> { + ) -> Expression<'a> { let mut expressions = self.ast.vec1(first_expression); while self.eat(Kind::Comma) { - let expression = self.parse_assignment_expression_or_higher()?; + let expression = self.parse_assignment_expression_or_higher(); expressions.push(expression); } - Ok(self.ast.expression_sequence(self.end_span(span), expressions)) + self.ast.expression_sequence(self.end_span(span), expressions) } /// ``AwaitExpression`[Yield]` : /// await `UnaryExpression`[?Yield, +Await] - fn parse_await_expression(&mut self, lhs_span: u32) -> Result> { + fn parse_await_expression(&mut self, lhs_span: u32) -> Expression<'a> { let span = self.start_span(); if !self.ctx.has_await() { self.error(diagnostics::await_expression(self.cur_token().span())); @@ -1331,23 +1325,23 @@ impl<'a> ParserImpl<'a> { self.bump_any(); let argument = self.context(Context::Await, Context::empty(), |p| { p.parse_simple_unary_expression(lhs_span) - })?; - Ok(self.ast.expression_await(self.end_span(span), argument)) + }); + self.ast.expression_await(self.end_span(span), argument) } /// `Decorator`[Yield, Await]: /// `DecoratorMemberExpression`[?Yield, ?Await] /// ( `Expression`[+In, ?Yield, ?Await] ) /// `DecoratorCallExpression` - pub(crate) fn parse_decorator(&mut self) -> Result> { + pub(crate) fn parse_decorator(&mut self) -> Decorator<'a> { let span = self.start_span(); self.bump_any(); // bump @ let expr = self.context( Context::Decorator, Context::empty(), Self::parse_lhs_expression_or_higher, - )?; - Ok(self.ast.decorator(self.end_span(span), expr)) + ); + self.ast.decorator(self.end_span(span), expr) } fn is_update_expression(&self) -> bool { diff --git a/crates/oxc_parser/src/js/function.rs b/crates/oxc_parser/src/js/function.rs index 97865474ac6b9..519378ae576e5 100644 --- a/crates/oxc_parser/src/js/function.rs +++ b/crates/oxc_parser/src/js/function.rs @@ -1,6 +1,5 @@ use oxc_allocator::Box; use oxc_ast::ast::*; -use oxc_diagnostics::Result; use oxc_span::Span; use super::FunctionKind; @@ -28,28 +27,28 @@ impl<'a> ParserImpl<'a> { && !self.peek_token().is_on_new_line } - pub(crate) fn parse_function_body(&mut self) -> Result>> { + pub(crate) fn parse_function_body(&mut self) -> Box<'a, FunctionBody<'a>> { let span = self.start_span(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let (directives, statements) = self.context(Context::Return, Context::empty(), |p| { p.parse_directives_and_statements(/* is_top_level */ false) - })?; + }); - self.expect(Kind::RCurly)?; - Ok(self.ast.alloc_function_body(self.end_span(span), directives, statements)) + self.expect(Kind::RCurly); + self.ast.alloc_function_body(self.end_span(span), directives, statements) } pub(crate) fn parse_formal_parameters( &mut self, params_kind: FormalParameterKind, - ) -> Result<(Option>, Box<'a, FormalParameters<'a>>)> { + ) -> (Option>, Box<'a, FormalParameters<'a>>) { let span = self.start_span(); - self.expect(Kind::LParen)?; + self.expect(Kind::LParen); let this_param = if self.is_ts && self.at(Kind::This) { - let param = self.parse_ts_this_parameter()?; + let param = self.parse_ts_this_parameter(); if !self.at(Kind::RParen) { - self.expect(Kind::Comma)?; + self.expect(Kind::Comma); } Some(param) } else { @@ -59,11 +58,11 @@ impl<'a> ParserImpl<'a> { Kind::RParen, Self::parse_formal_parameter, Self::parse_rest_parameter, - )?; - self.expect(Kind::RParen)?; + ); + self.expect(Kind::RParen); let formal_parameters = self.ast.alloc_formal_parameters(self.end_span(span), params_kind, list, rest); - Ok((this_param, formal_parameters)) + (this_param, formal_parameters) } fn parse_parameter_modifiers(&mut self) -> Modifiers<'a> { @@ -78,24 +77,24 @@ impl<'a> ParserImpl<'a> { modifiers } - fn parse_formal_parameter(&mut self) -> Result> { + fn parse_formal_parameter(&mut self) -> FormalParameter<'a> { let span = self.start_span(); - self.eat_decorators()?; + self.eat_decorators(); let modifiers = self.parse_parameter_modifiers(); - let pattern = self.parse_binding_pattern_with_initializer()?; + let pattern = self.parse_binding_pattern_with_initializer(); let decorators = self.consume_decorators(); - Ok(self.ast.formal_parameter( + self.ast.formal_parameter( self.end_span(span), decorators, pattern, modifiers.accessibility(), modifiers.contains_readonly(), modifiers.contains_override(), - )) + ) } - fn parse_rest_parameter(&mut self) -> Result> { - let element = self.parse_rest_element()?; + fn parse_rest_parameter(&mut self) -> BindingRestElement<'a> { + let element = self.parse_rest_element(); if self.at(Kind::Comma) { if matches!(self.peek_kind(), Kind::RCurly | Kind::RBrack) { let span = self.cur_token().span(); @@ -106,7 +105,7 @@ impl<'a> ParserImpl<'a> { self.error(diagnostics::rest_parameter_last(element.span)); } } - Ok(element) + element } pub(crate) fn parse_function( @@ -118,24 +117,24 @@ impl<'a> ParserImpl<'a> { func_kind: FunctionKind, param_kind: FormalParameterKind, modifiers: &Modifiers<'a>, - ) -> Result>> { + ) -> Box<'a, Function<'a>> { let ctx = self.ctx; self.ctx = self.ctx.and_in(true).and_await(r#async).and_yield(generator); - let type_parameters = self.parse_ts_type_parameters()?; + let type_parameters = self.parse_ts_type_parameters(); - let (this_param, params) = self.parse_formal_parameters(param_kind)?; + let (this_param, params) = self.parse_formal_parameters(param_kind); let return_type = - self.parse_ts_return_type_annotation(Kind::Colon, /* is_type */ true)?; + self.parse_ts_return_type_annotation(Kind::Colon, /* is_type */ true); - let body = if self.at(Kind::LCurly) { Some(self.parse_function_body()?) } else { None }; + let body = if self.at(Kind::LCurly) { Some(self.parse_function_body()) } else { None }; self.ctx = self.ctx.and_in(ctx.has_in()).and_await(ctx.has_await()).and_yield(ctx.has_yield()); if !self.is_ts && body.is_none() { - return Err(self.unexpected()); + return self.unexpected(); } let function_type = match func_kind { @@ -159,7 +158,7 @@ impl<'a> ParserImpl<'a> { if FunctionType::TSDeclareFunction == function_type || FunctionType::TSEmptyBodyFunctionExpression == function_type { - self.asi()?; + self.asi(); } self.verify_modifiers( @@ -168,7 +167,7 @@ impl<'a> ParserImpl<'a> { diagnostics::modifier_cannot_be_used_here, ); - Ok(self.ast.alloc_function( + self.ast.alloc_function( self.end_span(span), function_type, id, @@ -180,16 +179,16 @@ impl<'a> ParserImpl<'a> { params, return_type, body, - )) + ) } /// [Function Declaration](https://tc39.es/ecma262/#prod-FunctionDeclaration) pub(crate) fn parse_function_declaration( &mut self, stmt_ctx: StatementContext, - ) -> Result> { + ) -> Statement<'a> { let func_kind = FunctionKind::Declaration; - let decl = self.parse_function_impl(func_kind)?; + let decl = self.parse_function_impl(func_kind); if stmt_ctx.is_single_statement() { if decl.r#async { self.error(diagnostics::async_function_declaration(Span::new( @@ -203,20 +202,17 @@ impl<'a> ParserImpl<'a> { ))); } } - Ok(Statement::FunctionDeclaration(decl)) + Statement::FunctionDeclaration(decl) } /// Parse function implementation in Javascript, cursor /// at `function` or `async function` - pub(crate) fn parse_function_impl( - &mut self, - func_kind: FunctionKind, - ) -> Result>> { + pub(crate) fn parse_function_impl(&mut self, func_kind: FunctionKind) -> Box<'a, Function<'a>> { let span = self.start_span(); let r#async = self.eat(Kind::Async); - self.expect(Kind::Function)?; + self.expect(Kind::Function); let generator = self.eat(Kind::Star); - let id = self.parse_function_id(func_kind, r#async, generator)?; + let id = self.parse_function_id(func_kind, r#async, generator); self.parse_function( span, id, @@ -235,11 +231,11 @@ impl<'a> ParserImpl<'a> { start_span: u32, func_kind: FunctionKind, modifiers: &Modifiers<'a>, - ) -> Result>> { + ) -> Box<'a, Function<'a>> { let r#async = modifiers.contains(ModifierKind::Async); - self.expect(Kind::Function)?; + self.expect(Kind::Function); let generator = self.eat(Kind::Star); - let id = self.parse_function_id(func_kind, r#async, generator)?; + let id = self.parse_function_id(func_kind, r#async, generator); self.parse_function( start_span, id, @@ -252,16 +248,12 @@ impl<'a> ParserImpl<'a> { } /// [Function Expression](https://tc39.es/ecma262/#prod-FunctionExpression) - pub(crate) fn parse_function_expression( - &mut self, - span: u32, - r#async: bool, - ) -> Result> { + pub(crate) fn parse_function_expression(&mut self, span: u32, r#async: bool) -> Expression<'a> { let func_kind = FunctionKind::Expression; - self.expect(Kind::Function)?; + self.expect(Kind::Function); let generator = self.eat(Kind::Star); - let id = self.parse_function_id(func_kind, r#async, generator)?; + let id = self.parse_function_id(func_kind, r#async, generator); let function = self.parse_function( span, id, @@ -270,8 +262,8 @@ impl<'a> ParserImpl<'a> { func_kind, FormalParameterKind::FormalParameter, &Modifiers::empty(), - )?; - Ok(Expression::FunctionExpression(function)) + ); + Expression::FunctionExpression(function) } /// Section 15.4 Method Definitions @@ -282,11 +274,7 @@ impl<'a> ParserImpl<'a> { /// async `ClassElementName` /// `AsyncGeneratorMethod` /// async * `ClassElementName` - pub(crate) fn parse_method( - &mut self, - r#async: bool, - generator: bool, - ) -> Result>> { + pub(crate) fn parse_method(&mut self, r#async: bool, generator: bool) -> Box<'a, Function<'a>> { let span = self.start_span(); self.parse_function( span, @@ -303,7 +291,7 @@ impl<'a> ParserImpl<'a> { /// yield /// yield [no `LineTerminator` here] `AssignmentExpression` /// yield [no `LineTerminator` here] * `AssignmentExpression` - pub(crate) fn parse_yield_expression(&mut self) -> Result> { + pub(crate) fn parse_yield_expression(&mut self) -> Expression<'a> { let span = self.start_span(); self.bump_any(); // advance `yield` @@ -329,12 +317,12 @@ impl<'a> ParserImpl<'a> { ); if !not_assignment_expr || delegate { self.ctx = self.ctx.union_yield_if(true); - argument = Some(self.parse_assignment_expression_or_higher()?); + argument = Some(self.parse_assignment_expression_or_higher()); self.ctx = self.ctx.and_yield(has_yield); } } - Ok(self.ast.expression_yield(self.end_span(span), delegate, argument)) + self.ast.expression_yield(self.end_span(span), delegate, argument) } // id: None - for AnonymousDefaultExportedFunctionDeclaration @@ -343,7 +331,7 @@ impl<'a> ParserImpl<'a> { kind: FunctionKind, r#async: bool, generator: bool, - ) -> Result>> { + ) -> Option> { let ctx = self.ctx; if kind.is_expression() { self.ctx = self.ctx.and_await(r#async).and_yield(generator); @@ -360,11 +348,11 @@ impl<'a> ParserImpl<'a> { Kind::LParen => { self.error(diagnostics::expect_function_name(self.cur_token().span())); } - kind if kind.is_reserved_keyword() => self.expect_without_advance(Kind::Ident)?, + kind if kind.is_reserved_keyword() => self.expect_without_advance(Kind::Ident), _ => {} } } - Ok(id) + id } } diff --git a/crates/oxc_parser/src/js/grammar.rs b/crates/oxc_parser/src/js/grammar.rs index 9eea43e0118c1..ddc0a61d5b262 100644 --- a/crates/oxc_parser/src/js/grammar.rs +++ b/crates/oxc_parser/src/js/grammar.rs @@ -1,69 +1,67 @@ //! Cover Grammar for Destructuring Assignment use oxc_ast::ast::*; -use oxc_diagnostics::Result; use oxc_span::GetSpan; use crate::{ParserImpl, diagnostics}; pub trait CoverGrammar<'a, T>: Sized { - fn cover(value: T, p: &mut ParserImpl<'a>) -> Result; + fn cover(value: T, p: &mut ParserImpl<'a>) -> Self; } impl<'a> CoverGrammar<'a, Expression<'a>> for AssignmentTarget<'a> { - fn cover(expr: Expression<'a>, p: &mut ParserImpl<'a>) -> Result { + fn cover(expr: Expression<'a>, p: &mut ParserImpl<'a>) -> Self { match expr { Expression::ArrayExpression(array_expr) => { - ArrayAssignmentTarget::cover(array_expr.unbox(), p) - .map(|pat| AssignmentTarget::ArrayAssignmentTarget(p.alloc(pat))) + let pat = ArrayAssignmentTarget::cover(array_expr.unbox(), p); + AssignmentTarget::ArrayAssignmentTarget(p.alloc(pat)) } Expression::ObjectExpression(object_expr) => { - ObjectAssignmentTarget::cover(object_expr.unbox(), p) - .map(|pat| AssignmentTarget::ObjectAssignmentTarget(p.alloc(pat))) + let pat = ObjectAssignmentTarget::cover(object_expr.unbox(), p); + AssignmentTarget::ObjectAssignmentTarget(p.alloc(pat)) } - _ => SimpleAssignmentTarget::cover(expr, p).map(AssignmentTarget::from), + _ => AssignmentTarget::from(SimpleAssignmentTarget::cover(expr, p)), } } } impl<'a> CoverGrammar<'a, Expression<'a>> for SimpleAssignmentTarget<'a> { - #[expect(clippy::only_used_in_recursion)] - fn cover(expr: Expression<'a>, p: &mut ParserImpl<'a>) -> Result { + fn cover(expr: Expression<'a>, p: &mut ParserImpl<'a>) -> Self { match expr { Expression::Identifier(ident) => { - Ok(SimpleAssignmentTarget::AssignmentTargetIdentifier(ident)) + SimpleAssignmentTarget::AssignmentTargetIdentifier(ident) } match_member_expression!(Expression) => { let member_expr = expr.into_member_expression(); - Ok(SimpleAssignmentTarget::from(member_expr)) + SimpleAssignmentTarget::from(member_expr) } Expression::ParenthesizedExpression(expr) => { let span = expr.span; match expr.unbox().expression { Expression::ObjectExpression(_) | Expression::ArrayExpression(_) => { - Err(diagnostics::invalid_assignment(span)) + p.fatal_error(diagnostics::invalid_assignment(span)) } expr => SimpleAssignmentTarget::cover(expr, p), } } - Expression::TSAsExpression(expr) => Ok(SimpleAssignmentTarget::TSAsExpression(expr)), + Expression::TSAsExpression(expr) => SimpleAssignmentTarget::TSAsExpression(expr), Expression::TSSatisfiesExpression(expr) => { - Ok(SimpleAssignmentTarget::TSSatisfiesExpression(expr)) + SimpleAssignmentTarget::TSSatisfiesExpression(expr) } Expression::TSNonNullExpression(expr) => { - Ok(SimpleAssignmentTarget::TSNonNullExpression(expr)) + SimpleAssignmentTarget::TSNonNullExpression(expr) } - Expression::TSTypeAssertion(expr) => Ok(SimpleAssignmentTarget::TSTypeAssertion(expr)), + Expression::TSTypeAssertion(expr) => SimpleAssignmentTarget::TSTypeAssertion(expr), Expression::TSInstantiationExpression(expr) => { - Err(diagnostics::invalid_lhs_assignment(expr.span())) + p.fatal_error(diagnostics::invalid_lhs_assignment(expr.span())) } - expr => Err(diagnostics::invalid_assignment(expr.span())), + expr => p.fatal_error(diagnostics::invalid_assignment(expr.span())), } } } impl<'a> CoverGrammar<'a, ArrayExpression<'a>> for ArrayAssignmentTarget<'a> { - fn cover(expr: ArrayExpression<'a>, p: &mut ParserImpl<'a>) -> Result { + fn cover(expr: ArrayExpression<'a>, p: &mut ParserImpl<'a>) -> Self { let mut elements = p.ast.vec(); let mut rest = None; @@ -72,54 +70,54 @@ impl<'a> CoverGrammar<'a, ArrayExpression<'a>> for ArrayAssignmentTarget<'a> { match elem { match_expression!(ArrayExpressionElement) => { let expr = elem.into_expression(); - let target = AssignmentTargetMaybeDefault::cover(expr, p)?; + let target = AssignmentTargetMaybeDefault::cover(expr, p); elements.push(Some(target)); } ArrayExpressionElement::SpreadElement(elem) => { if i == len - 1 { rest = Some(p.ast.assignment_target_rest( elem.span, - AssignmentTarget::cover(elem.unbox().argument, p)?, + AssignmentTarget::cover(elem.unbox().argument, p), )); if let Some(span) = p.state.trailing_commas.get(&expr.span.start) { p.error(diagnostics::binding_rest_element_trailing_comma(*span)); } } else { let error = diagnostics::spread_last_element(elem.span); - return Err(p.set_fatal_error(error)); + return p.fatal_error(error); } } ArrayExpressionElement::Elision(_) => elements.push(None), } } - Ok(p.ast.array_assignment_target(expr.span, elements, rest)) + p.ast.array_assignment_target(expr.span, elements, rest) } } impl<'a> CoverGrammar<'a, Expression<'a>> for AssignmentTargetMaybeDefault<'a> { - fn cover(expr: Expression<'a>, p: &mut ParserImpl<'a>) -> Result { + fn cover(expr: Expression<'a>, p: &mut ParserImpl<'a>) -> Self { match expr { Expression::AssignmentExpression(assignment_expr) => { - let target = AssignmentTargetWithDefault::cover(assignment_expr.unbox(), p)?; - Ok(AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(p.alloc(target))) + let target = AssignmentTargetWithDefault::cover(assignment_expr.unbox(), p); + AssignmentTargetMaybeDefault::AssignmentTargetWithDefault(p.alloc(target)) } expr => { - let target = AssignmentTarget::cover(expr, p)?; - Ok(AssignmentTargetMaybeDefault::from(target)) + let target = AssignmentTarget::cover(expr, p); + AssignmentTargetMaybeDefault::from(target) } } } } impl<'a> CoverGrammar<'a, AssignmentExpression<'a>> for AssignmentTargetWithDefault<'a> { - fn cover(expr: AssignmentExpression<'a>, p: &mut ParserImpl<'a>) -> Result { - Ok(p.ast.assignment_target_with_default(expr.span, expr.left, expr.right)) + fn cover(expr: AssignmentExpression<'a>, p: &mut ParserImpl<'a>) -> Self { + p.ast.assignment_target_with_default(expr.span, expr.left, expr.right) } } impl<'a> CoverGrammar<'a, ObjectExpression<'a>> for ObjectAssignmentTarget<'a> { - fn cover(expr: ObjectExpression<'a>, p: &mut ParserImpl<'a>) -> Result { + fn cover(expr: ObjectExpression<'a>, p: &mut ParserImpl<'a>) -> Self { let mut properties = p.ast.vec(); let mut rest = None; @@ -127,51 +125,51 @@ impl<'a> CoverGrammar<'a, ObjectExpression<'a>> for ObjectAssignmentTarget<'a> { for (i, elem) in expr.properties.into_iter().enumerate() { match elem { ObjectPropertyKind::ObjectProperty(property) => { - let target = AssignmentTargetProperty::cover(property.unbox(), p)?; + let target = AssignmentTargetProperty::cover(property.unbox(), p); properties.push(target); } ObjectPropertyKind::SpreadProperty(spread) => { if i == len - 1 { rest = Some(p.ast.assignment_target_rest( spread.span, - AssignmentTarget::cover(spread.unbox().argument, p)?, + AssignmentTarget::cover(spread.unbox().argument, p), )); } else { - return Err(diagnostics::spread_last_element(spread.span)); + return p.fatal_error(diagnostics::spread_last_element(spread.span)); } } } } - Ok(p.ast.object_assignment_target(expr.span, properties, rest)) + p.ast.object_assignment_target(expr.span, properties, rest) } } impl<'a> CoverGrammar<'a, ObjectProperty<'a>> for AssignmentTargetProperty<'a> { - fn cover(property: ObjectProperty<'a>, p: &mut ParserImpl<'a>) -> Result { + fn cover(property: ObjectProperty<'a>, p: &mut ParserImpl<'a>) -> Self { if property.shorthand { let binding = match property.key { PropertyKey::StaticIdentifier(ident) => { let ident = ident.unbox(); p.ast.identifier_reference(ident.span, ident.name) } - _ => return Err(p.unexpected()), + _ => return p.unexpected(), }; // convert `CoverInitializedName` let init = p.state.cover_initialized_name.remove(&property.span.start).map(|e| e.right); - Ok(p.ast.assignment_target_property_assignment_target_property_identifier( + p.ast.assignment_target_property_assignment_target_property_identifier( property.span, binding, init, - )) + ) } else { - let binding = AssignmentTargetMaybeDefault::cover(property.value, p)?; - Ok(p.ast.assignment_target_property_assignment_target_property_property( + let binding = AssignmentTargetMaybeDefault::cover(property.value, p); + p.ast.assignment_target_property_assignment_target_property_property( property.span, property.key, binding, property.computed, - )) + ) } } } diff --git a/crates/oxc_parser/src/js/module.rs b/crates/oxc_parser/src/js/module.rs index cb75cff2de0bf..14b2bb1ef6a46 100644 --- a/crates/oxc_parser/src/js/module.rs +++ b/crates/oxc_parser/src/js/module.rs @@ -1,6 +1,5 @@ use oxc_allocator::{Box, Vec}; use oxc_ast::{NONE, ast::*}; -use oxc_diagnostics::Result; use oxc_span::GetSpan; use rustc_hash::FxHashMap; @@ -14,17 +13,17 @@ impl<'a> ParserImpl<'a> { &mut self, span: u32, phase: Option, - ) -> Result> { - self.expect(Kind::LParen)?; + ) -> Expression<'a> { + self.expect(Kind::LParen); if self.eat(Kind::RParen) { let error = diagnostics::import_requires_a_specifier(self.end_span(span)); - return Err(self.set_fatal_error(error)); + return self.fatal_error(error); } let has_in = self.ctx.has_in(); self.ctx = self.ctx.and_in(true); - let expression = self.parse_assignment_expression_or_higher()?; + let expression = self.parse_assignment_expression_or_higher(); let arguments = if self.eat(Kind::Comma) && !self.at(Kind::RParen) { - Some(self.parse_assignment_expression_or_higher()?) + Some(self.parse_assignment_expression_or_higher()) } else { None }; @@ -32,17 +31,17 @@ impl<'a> ParserImpl<'a> { self.bump(Kind::Comma); if !self.eat(Kind::RParen) { let error = diagnostics::import_arguments(self.end_span(span)); - return Err(self.set_fatal_error(error)); + return self.fatal_error(error); } self.ctx = self.ctx.and_in(has_in); let expr = self.ast.alloc_import_expression(self.end_span(span), expression, arguments, phase); self.module_record_builder.visit_import_expression(&expr); - Ok(Expression::ImportExpression(expr)) + Expression::ImportExpression(expr) } /// Section 16.2.2 Import Declaration - pub(crate) fn parse_import_declaration(&mut self) -> Result> { + pub(crate) fn parse_import_declaration(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // advance `import` @@ -53,8 +52,8 @@ impl<'a> ParserImpl<'a> { && self.peek_kind().is_binding_identifier() && self.nth_at(2, Kind::Eq))) { - let decl = self.parse_ts_import_equals_declaration(span)?; - return Ok(Statement::from(decl)); + let decl = self.parse_ts_import_equals_declaration(span); + return Statement::from(decl); } // `import type ...` @@ -81,15 +80,14 @@ impl<'a> ParserImpl<'a> { // import "source" None } else { - Some(self.parse_import_declaration_specifiers(import_kind)?) + Some(self.parse_import_declaration_specifiers(import_kind)) }; - let source = self.parse_literal_string()?; - let with_clause = self.parse_import_attributes()?; - self.asi()?; + let source = self.parse_literal_string(); + let with_clause = self.parse_import_attributes(); + self.asi(); let span = self.end_span(span); - Ok(self - .ast + self.ast .module_declaration_import_declaration( span, specifiers, @@ -98,67 +96,67 @@ impl<'a> ParserImpl<'a> { with_clause, import_kind, ) - .into()) + .into() } // Full Syntax: fn parse_import_declaration_specifiers( &mut self, import_kind: ImportOrExportKind, - ) -> Result>> { + ) -> Vec<'a, ImportDeclarationSpecifier<'a>> { let mut specifiers = self.ast.vec(); // import defaultExport from "module-name"; if self.cur_kind().is_binding_identifier() { - specifiers.push(self.parse_import_default_specifier()?); + specifiers.push(self.parse_import_default_specifier()); if self.eat(Kind::Comma) { match self.cur_kind() { // import defaultExport, * as name from "module-name"; - Kind::Star => specifiers.push(self.parse_import_namespace_specifier()?), + Kind::Star => specifiers.push(self.parse_import_namespace_specifier()), // import defaultExport, { export1 [ , [...] ] } from "module-name"; Kind::LCurly => { - let mut import_specifiers = self.parse_import_specifiers(import_kind)?; + let mut import_specifiers = self.parse_import_specifiers(import_kind); specifiers.append(&mut import_specifiers); } - _ => return Err(self.unexpected()), + _ => return self.unexpected(), } } // import * as name from "module-name"; } else if self.at(Kind::Star) { - specifiers.push(self.parse_import_namespace_specifier()?); + specifiers.push(self.parse_import_namespace_specifier()); // import { export1 , export2 as alias2 , [...] } from "module-name"; } else if self.at(Kind::LCurly) { - let mut import_specifiers = self.parse_import_specifiers(import_kind)?; + let mut import_specifiers = self.parse_import_specifiers(import_kind); specifiers.append(&mut import_specifiers); } - self.expect(Kind::From)?; - Ok(specifiers) + self.expect(Kind::From); + specifiers } // import default from "module-name" - fn parse_import_default_specifier(&mut self) -> Result> { + fn parse_import_default_specifier(&mut self) -> ImportDeclarationSpecifier<'a> { let span = self.start_span(); - let local = self.parse_binding_identifier()?; + let local = self.parse_binding_identifier(); let span = self.end_span(span); - Ok(self.ast.import_declaration_specifier_import_default_specifier(span, local)) + self.ast.import_declaration_specifier_import_default_specifier(span, local) } // import * as name from "module-name" - fn parse_import_namespace_specifier(&mut self) -> Result> { + fn parse_import_namespace_specifier(&mut self) -> ImportDeclarationSpecifier<'a> { let span = self.start_span(); self.bump_any(); // advance `*` - self.expect(Kind::As)?; - let local = self.parse_binding_identifier()?; + self.expect(Kind::As); + let local = self.parse_binding_identifier(); let span = self.end_span(span); - Ok(self.ast.import_declaration_specifier_import_namespace_specifier(span, local)) + self.ast.import_declaration_specifier_import_namespace_specifier(span, local) } // import { export1 , export2 as alias2 , [...] } from "module-name"; fn parse_import_specifiers( &mut self, import_kind: ImportOrExportKind, - ) -> Result>> { - self.expect(Kind::LCurly)?; + ) -> Vec<'a, ImportDeclarationSpecifier<'a>> { + self.expect(Kind::LCurly); let list = self.context(Context::empty(), self.ctx, |p| { p.parse_delimited_list( Kind::RCurly, @@ -166,22 +164,22 @@ impl<'a> ParserImpl<'a> { /* trailing_separator */ true, |parser| parser.parse_import_specifier(import_kind), ) - })?; - self.expect(Kind::RCurly)?; - Ok(list) + }); + self.expect(Kind::RCurly); + list } /// [Import Attributes](https://tc39.es/proposal-import-attributes) - fn parse_import_attributes(&mut self) -> Result>> { + fn parse_import_attributes(&mut self) -> Option> { let attributes_keyword = match self.cur_kind() { - Kind::Assert if !self.cur_token().is_on_new_line => self.parse_identifier_name()?, - Kind::With => self.parse_identifier_name()?, + Kind::Assert if !self.cur_token().is_on_new_line => self.parse_identifier_name(), + Kind::With => self.parse_identifier_name(), _ => { - return Ok(None); + return None; } }; let span = self.start_span(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let with_entries = self.context(Context::empty(), self.ctx, |p| { p.parse_delimited_list( Kind::RCurly, @@ -189,8 +187,8 @@ impl<'a> ParserImpl<'a> { /*trailing_separator*/ true, Self::parse_import_attribute, ) - })?; - self.expect(Kind::RCurly)?; + }); + self.expect(Kind::RCurly); let mut keys = FxHashMap::default(); for e in &with_entries { @@ -201,73 +199,75 @@ impl<'a> ParserImpl<'a> { } } - Ok(Some(self.ast.with_clause(self.end_span(span), attributes_keyword, with_entries))) + Some(self.ast.with_clause(self.end_span(span), attributes_keyword, with_entries)) } - fn parse_import_attribute(&mut self) -> Result> { + fn parse_import_attribute(&mut self) -> ImportAttribute<'a> { let span = self.start_span(); let key = match self.cur_kind() { - Kind::Str => ImportAttributeKey::StringLiteral(self.parse_literal_string()?), - _ => ImportAttributeKey::Identifier(self.parse_identifier_name()?), + Kind::Str => ImportAttributeKey::StringLiteral(self.parse_literal_string()), + _ => ImportAttributeKey::Identifier(self.parse_identifier_name()), }; - self.expect(Kind::Colon)?; - let value = self.parse_literal_string()?; - Ok(self.ast.import_attribute(self.end_span(span), key, value)) + self.expect(Kind::Colon); + let value = self.parse_literal_string(); + self.ast.import_attribute(self.end_span(span), key, value) } pub(crate) fn parse_ts_export_assignment_declaration( &mut self, start_span: u32, - ) -> Result>> { - self.expect(Kind::Eq)?; - let expression = self.parse_assignment_expression_or_higher()?; - self.asi()?; - Ok(self.ast.alloc_ts_export_assignment(self.end_span(start_span), expression)) + ) -> Box<'a, TSExportAssignment<'a>> { + self.expect(Kind::Eq); + let expression = self.parse_assignment_expression_or_higher(); + self.asi(); + self.ast.alloc_ts_export_assignment(self.end_span(start_span), expression) } pub(crate) fn parse_ts_export_namespace( &mut self, start_span: u32, - ) -> Result>> { - self.expect(Kind::As)?; - self.expect(Kind::Namespace)?; - let id = self.parse_identifier_name()?; - self.asi()?; - Ok(self.ast.alloc_ts_namespace_export_declaration(self.end_span(start_span), id)) + ) -> Box<'a, TSNamespaceExportDeclaration<'a>> { + self.expect(Kind::As); + self.expect(Kind::Namespace); + let id = self.parse_identifier_name(); + self.asi(); + self.ast.alloc_ts_namespace_export_declaration(self.end_span(start_span), id) } /// [Exports](https://tc39.es/ecma262/#sec-exports) - pub(crate) fn parse_export_declaration(&mut self) -> Result> { + pub(crate) fn parse_export_declaration(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // advance `export` let decl = match self.cur_kind() { - Kind::Eq if self.is_ts => self - .parse_ts_export_assignment_declaration(span) - .map(ModuleDeclaration::TSExportAssignment), - Kind::As if self.peek_at(Kind::Namespace) && self.is_ts => self - .parse_ts_export_namespace(span) - .map(ModuleDeclaration::TSNamespaceExportDeclaration), - Kind::Default => self - .parse_export_default_declaration(span) - .map(ModuleDeclaration::ExportDefaultDeclaration), + Kind::Eq if self.is_ts => ModuleDeclaration::TSExportAssignment( + self.parse_ts_export_assignment_declaration(span), + ), + Kind::As if self.peek_at(Kind::Namespace) && self.is_ts => { + ModuleDeclaration::TSNamespaceExportDeclaration( + self.parse_ts_export_namespace(span), + ) + } + Kind::Default => ModuleDeclaration::ExportDefaultDeclaration( + self.parse_export_default_declaration(span), + ), Kind::Star => { - self.parse_export_all_declaration(span).map(ModuleDeclaration::ExportAllDeclaration) + ModuleDeclaration::ExportAllDeclaration(self.parse_export_all_declaration(span)) + } + Kind::LCurly => { + ModuleDeclaration::ExportNamedDeclaration(self.parse_export_named_specifiers(span)) + } + Kind::Type if self.peek_at(Kind::LCurly) && self.is_ts => { + ModuleDeclaration::ExportNamedDeclaration(self.parse_export_named_specifiers(span)) } - Kind::LCurly => self - .parse_export_named_specifiers(span) - .map(ModuleDeclaration::ExportNamedDeclaration), - Kind::Type if self.peek_at(Kind::LCurly) && self.is_ts => self - .parse_export_named_specifiers(span) - .map(ModuleDeclaration::ExportNamedDeclaration), Kind::Type if self.peek_at(Kind::Star) => { - self.parse_export_all_declaration(span).map(ModuleDeclaration::ExportAllDeclaration) + ModuleDeclaration::ExportAllDeclaration(self.parse_export_all_declaration(span)) } - _ => self - .parse_export_named_declaration(span) - .map(ModuleDeclaration::ExportNamedDeclaration), - }?; - Ok(Statement::from(decl)) + _ => { + ModuleDeclaration::ExportNamedDeclaration(self.parse_export_named_declaration(span)) + } + }; + Statement::from(decl) } // export NamedExports ; @@ -281,12 +281,9 @@ impl<'a> ParserImpl<'a> { // ExportSpecifier : // ModuleExportName // ModuleExportName as ModuleExportName - fn parse_export_named_specifiers( - &mut self, - span: u32, - ) -> Result>> { + fn parse_export_named_specifiers(&mut self, span: u32) -> Box<'a, ExportNamedDeclaration<'a>> { let export_kind = self.parse_import_or_export_kind(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let mut specifiers = self.context(Context::empty(), self.ctx, |p| { p.parse_delimited_list( Kind::RCurly, @@ -294,11 +291,11 @@ impl<'a> ParserImpl<'a> { /* trailing_separator */ true, |parser| parser.parse_export_named_specifier(export_kind), ) - })?; - self.expect(Kind::RCurly)?; + }); + self.expect(Kind::RCurly); let (source, with_clause) = if self.eat(Kind::From) && self.cur_kind().is_literal() { - let source = self.parse_literal_string()?; - (Some(source), self.parse_import_attributes()?) + let source = self.parse_literal_string(); + (Some(source), self.parse_import_attributes()) } else { (None, None) }; @@ -341,47 +338,44 @@ impl<'a> ParserImpl<'a> { } } - self.asi()?; + self.asi(); let span = self.end_span(span); - Ok(self.ast.alloc_export_named_declaration( + self.ast.alloc_export_named_declaration( span, None, specifiers, source, export_kind, with_clause, - )) + ) } // export Declaration - fn parse_export_named_declaration( - &mut self, - span: u32, - ) -> Result>> { + fn parse_export_named_declaration(&mut self, span: u32) -> Box<'a, ExportNamedDeclaration<'a>> { let decl_span = self.start_span(); // For tc39/proposal-decorators // For more information, please refer to - self.eat_decorators()?; + self.eat_decorators(); let reserved_ctx = self.ctx; let modifiers = - if self.is_ts { self.eat_modifiers_before_declaration()? } else { Modifiers::empty() }; + if self.is_ts { self.eat_modifiers_before_declaration() } else { Modifiers::empty() }; self.ctx = self.ctx.union_ambient_if(modifiers.contains_declare()); - let declaration = self.parse_declaration(decl_span, &modifiers)?; + let declaration = self.parse_declaration(decl_span, &modifiers); let export_kind = if declaration.declare() || declaration.is_type() { ImportOrExportKind::Type } else { ImportOrExportKind::Value }; self.ctx = reserved_ctx; - Ok(self.ast.alloc_export_named_declaration( + self.ast.alloc_export_named_declaration( self.end_span(span), Some(declaration), self.ast.vec(), None, export_kind, NONE, - )) + ) } // export default HoistableDeclaration[~Yield, +Await, +Default] @@ -390,52 +384,52 @@ impl<'a> ParserImpl<'a> { fn parse_export_default_declaration( &mut self, span: u32, - ) -> Result>> { + ) -> Box<'a, ExportDefaultDeclaration<'a>> { let exported = self.parse_keyword_identifier(Kind::Default); let decl_span = self.start_span(); let has_no_side_effects_comment = self.lexer.trivia_builder.previous_token_has_no_side_effects_comment(); // For tc39/proposal-decorators // For more information, please refer to - self.eat_decorators()?; + self.eat_decorators(); let declaration = match self.cur_kind() { - Kind::Class => self - .parse_class_declaration(decl_span, /* modifiers */ &Modifiers::empty()) - .map(ExportDefaultDeclarationKind::ClassDeclaration)?, + Kind::Class => ExportDefaultDeclarationKind::ClassDeclaration( + self.parse_class_declaration(decl_span, /* modifiers */ &Modifiers::empty()), + ), _ if self.at(Kind::Abstract) && self.peek_at(Kind::Class) && self.is_ts => { // eat the abstract modifier - let modifiers = self.eat_modifiers_before_declaration()?; - self.parse_class_declaration(decl_span, &modifiers) - .map(ExportDefaultDeclarationKind::ClassDeclaration)? + let modifiers = self.eat_modifiers_before_declaration(); + ExportDefaultDeclarationKind::ClassDeclaration( + self.parse_class_declaration(decl_span, &modifiers), + ) } _ if self.at(Kind::Interface) && !self.peek_token().is_on_new_line && self.is_ts => { - self.parse_ts_interface_declaration(decl_span, &Modifiers::empty()).map(|decl| { - match decl { - Declaration::TSInterfaceDeclaration(decl) => { - ExportDefaultDeclarationKind::TSInterfaceDeclaration(decl) - } - _ => unreachable!(), + let decl = self.parse_ts_interface_declaration(decl_span, &Modifiers::empty()); + match decl { + Declaration::TSInterfaceDeclaration(decl) => { + ExportDefaultDeclarationKind::TSInterfaceDeclaration(decl) } - })? + _ => unreachable!(), + } } _ if self.at_function_with_async() => { - let mut func = self.parse_function_impl(FunctionKind::DefaultExport)?; + let mut func = self.parse_function_impl(FunctionKind::DefaultExport); if has_no_side_effects_comment { func.pure = true; } ExportDefaultDeclarationKind::FunctionDeclaration(func) } _ => { - let decl = self - .parse_assignment_expression_or_higher() - .map(ExportDefaultDeclarationKind::from)?; - self.asi()?; + let decl = ExportDefaultDeclarationKind::from( + self.parse_assignment_expression_or_higher(), + ); + self.asi(); decl } }; let exported = ModuleExportName::IdentifierName(exported); let span = self.end_span(span); - Ok(self.ast.alloc_export_default_declaration(span, exported, declaration)) + self.ast.alloc_export_default_declaration(span, exported, declaration) } // export ExportFromClause FromClause ; @@ -443,19 +437,16 @@ impl<'a> ParserImpl<'a> { // * // * as ModuleExportName // NamedExports - fn parse_export_all_declaration( - &mut self, - span: u32, - ) -> Result>> { + fn parse_export_all_declaration(&mut self, span: u32) -> Box<'a, ExportAllDeclaration<'a>> { let export_kind = self.parse_import_or_export_kind(); self.bump_any(); // bump `star` - let exported = self.eat(Kind::As).then(|| self.parse_module_export_name()).transpose()?; - self.expect(Kind::From)?; - let source = self.parse_literal_string()?; - let with_clause = self.parse_import_attributes()?; - self.asi()?; + let exported = self.eat(Kind::As).then(|| self.parse_module_export_name()); + self.expect(Kind::From); + let source = self.parse_literal_string(); + let with_clause = self.parse_import_attributes(); + self.asi(); let span = self.end_span(span); - Ok(self.ast.alloc_export_all_declaration(span, exported, source, with_clause, export_kind)) + self.ast.alloc_export_all_declaration(span, exported, source, with_clause, export_kind) } // ImportSpecifier : @@ -464,7 +455,7 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_import_specifier( &mut self, parent_import_kind: ImportOrExportKind, - ) -> Result> { + ) -> ImportDeclarationSpecifier<'a> { let specifier_span = self.start_span(); let peek_kind = self.peek_kind(); let mut import_kind = ImportOrExportKind::Value; @@ -491,37 +482,37 @@ impl<'a> ParserImpl<'a> { self.bump_any(); } let (imported, local) = if self.peek_at(Kind::As) { - let imported = self.parse_module_export_name()?; + let imported = self.parse_module_export_name(); self.bump(Kind::As); - let local = self.parse_binding_identifier()?; + let local = self.parse_binding_identifier(); (imported, local) } else { - let local = self.parse_binding_identifier()?; + let local = self.parse_binding_identifier(); (self.ast.module_export_name_identifier_name(local.span, local.name), local) }; - Ok(self.ast.import_declaration_specifier_import_specifier( + self.ast.import_declaration_specifier_import_specifier( self.end_span(specifier_span), imported, local, import_kind, - )) + ) } // ModuleExportName : // IdentifierName // StringLiteral - pub(crate) fn parse_module_export_name(&mut self) -> Result> { + pub(crate) fn parse_module_export_name(&mut self) -> ModuleExportName<'a> { match self.cur_kind() { Kind::Str => { - let literal = self.parse_literal_string()?; + let literal = self.parse_literal_string(); // ModuleExportName : StringLiteral // It is a Syntax Error if IsStringWellFormedUnicode(the SV of StringLiteral) is false. if literal.lone_surrogates || !literal.is_string_well_formed_unicode() { self.error(diagnostics::export_lone_surrogate(literal.span)); } - Ok(ModuleExportName::StringLiteral(literal)) + ModuleExportName::StringLiteral(literal) } - _ => Ok(ModuleExportName::IdentifierName(self.parse_identifier_name()?)), + _ => ModuleExportName::IdentifierName(self.parse_identifier_name()), } } @@ -564,7 +555,7 @@ impl<'a> ParserImpl<'a> { fn parse_export_named_specifier( &mut self, parent_export_kind: ImportOrExportKind, - ) -> Result> { + ) -> ExportSpecifier<'a> { let specifier_span = self.start_span(); let peek_kind = self.peek_kind(); // export { type} // name: `type` @@ -596,9 +587,9 @@ impl<'a> ParserImpl<'a> { self.bump_any(); } - let local = self.parse_module_export_name()?; + let local = self.parse_module_export_name(); let exported = - if self.eat(Kind::As) { self.parse_module_export_name()? } else { local.clone() }; - Ok(self.ast.export_specifier(self.end_span(specifier_span), local, exported, export_kind)) + if self.eat(Kind::As) { self.parse_module_export_name() } else { local.clone() }; + self.ast.export_specifier(self.end_span(specifier_span), local, exported, export_kind) } } diff --git a/crates/oxc_parser/src/js/object.rs b/crates/oxc_parser/src/js/object.rs index 08c877749b740..6704442c62509 100644 --- a/crates/oxc_parser/src/js/object.rs +++ b/crates/oxc_parser/src/js/object.rs @@ -1,6 +1,5 @@ use oxc_allocator::Box; use oxc_ast::ast::*; -use oxc_diagnostics::Result; use oxc_syntax::operator::AssignmentOperator; use crate::{Context, ParserImpl, diagnostics, lexer::Kind, modifiers::Modifier}; @@ -11,9 +10,9 @@ impl<'a> ParserImpl<'a> { /// { } /// { `PropertyDefinitionList`[?Yield, ?Await] } /// { `PropertyDefinitionList`[?Yield, ?Await] , } - pub(crate) fn parse_object_expression(&mut self) -> Result>> { + pub(crate) fn parse_object_expression(&mut self) -> Box<'a, ObjectExpression<'a>> { let span = self.start_span(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let object_expression_properties = self.context(Context::In, Context::empty(), |p| { p.parse_delimited_list( Kind::RCurly, @@ -21,21 +20,21 @@ impl<'a> ParserImpl<'a> { /* trailing_separator */ false, Self::parse_object_expression_property, ) - })?; + }); self.eat(Kind::Comma); // Trailing Comma - self.expect(Kind::RCurly)?; - Ok(self.ast.alloc_object_expression(self.end_span(span), object_expression_properties)) + self.expect(Kind::RCurly); + self.ast.alloc_object_expression(self.end_span(span), object_expression_properties) } - fn parse_object_expression_property(&mut self) -> Result> { + fn parse_object_expression_property(&mut self) -> ObjectPropertyKind<'a> { match self.cur_kind() { - Kind::Dot3 => self.parse_spread_element().map(ObjectPropertyKind::SpreadProperty), - _ => self.parse_property_definition().map(ObjectPropertyKind::ObjectProperty), + Kind::Dot3 => ObjectPropertyKind::SpreadProperty(self.parse_spread_element()), + _ => ObjectPropertyKind::ObjectProperty(self.parse_property_definition()), } } /// `PropertyDefinition`[Yield, Await] - pub(crate) fn parse_property_definition(&mut self) -> Result>> { + pub(crate) fn parse_property_definition(&mut self) -> Box<'a, ObjectProperty<'a>> { let peek_kind = self.peek_kind(); let class_element_name = peek_kind.is_class_element_name_start(); match self.cur_kind() { @@ -85,15 +84,15 @@ impl<'a> ParserImpl<'a> { } _ => { let span = self.start_span(); - let (key, computed) = self.parse_property_name()?; + let (key, computed) = self.parse_property_name(); if self.at(Kind::Colon) { return self.parse_property_definition_assignment(span, key, computed); } if matches!(self.cur_kind(), Kind::LParen | Kind::LAngle | Kind::ShiftLeft) { - let method = self.parse_method(false, false)?; - return Ok(self.ast.alloc_object_property( + let method = self.parse_method(false, false); + return self.ast.alloc_object_property( self.end_span(span), PropertyKind::Init, key, @@ -101,35 +100,35 @@ impl<'a> ParserImpl<'a> { /* method */ true, /* shorthand */ false, /* computed */ computed, - )); + ); } - Err(self.unexpected()) + self.unexpected() } } } /// `PropertyDefinition`[Yield, Await] : /// ... `AssignmentExpression`[+In, ?Yield, ?Await] - pub(crate) fn parse_spread_element(&mut self) -> Result>> { + pub(crate) fn parse_spread_element(&mut self) -> Box<'a, SpreadElement<'a>> { let span = self.start_span(); self.bump_any(); // advance `...` - let argument = self.parse_assignment_expression_or_higher()?; - Ok(self.ast.alloc_spread_element(self.end_span(span), argument)) + let argument = self.parse_assignment_expression_or_higher(); + self.ast.alloc_spread_element(self.end_span(span), argument) } /// `PropertyDefinition`[Yield, Await] : /// `IdentifierReference`[?Yield, ?Await] /// `CoverInitializedName`[?Yield, ?Await] - fn parse_property_definition_shorthand(&mut self) -> Result>> { + fn parse_property_definition_shorthand(&mut self) -> Box<'a, ObjectProperty<'a>> { let span = self.start_span(); - let identifier = self.parse_identifier_reference()?; + let identifier = self.parse_identifier_reference(); let key = self.ast.alloc_identifier_name(identifier.span, identifier.name); // IdentifierReference ({ foo }) let value = Expression::Identifier(self.alloc(identifier.clone())); // CoverInitializedName ({ foo = bar }) if self.eat(Kind::Eq) { - let right = self.parse_assignment_expression_or_higher()?; + let right = self.parse_assignment_expression_or_higher(); let left = AssignmentTarget::AssignmentTargetIdentifier(self.alloc(identifier)); let expr = self.ast.assignment_expression( self.end_span(span), @@ -139,7 +138,7 @@ impl<'a> ParserImpl<'a> { ); self.state.cover_initialized_name.insert(span, expr); } - Ok(self.ast.alloc_object_property( + self.ast.alloc_object_property( self.end_span(span), PropertyKind::Init, PropertyKey::StaticIdentifier(key), @@ -147,7 +146,7 @@ impl<'a> ParserImpl<'a> { /* method */ false, /* shorthand */ true, /* computed */ false, - )) + ) } /// `PropertyDefinition`[Yield, Await] : @@ -157,10 +156,10 @@ impl<'a> ParserImpl<'a> { span: u32, key: PropertyKey<'a>, computed: bool, - ) -> Result>> { + ) -> Box<'a, ObjectProperty<'a>> { self.bump_any(); // bump `:` - let value = self.parse_assignment_expression_or_higher()?; - Ok(self.ast.alloc_object_property( + let value = self.parse_assignment_expression_or_higher(); + self.ast.alloc_object_property( self.end_span(span), PropertyKind::Init, key, @@ -168,54 +167,54 @@ impl<'a> ParserImpl<'a> { /* method */ false, /* shorthand */ false, /* computed */ computed, - )) + ) } /// `PropertyName`[Yield, Await] : /// `LiteralPropertyName` /// `ComputedPropertyName`[?Yield, ?Await] - pub(crate) fn parse_property_name(&mut self) -> Result<(PropertyKey<'a>, bool)> { + pub(crate) fn parse_property_name(&mut self) -> (PropertyKey<'a>, bool) { let mut computed = false; let key = match self.cur_kind() { - Kind::Str => self.parse_literal_expression().map(PropertyKey::from)?, - kind if kind.is_number() => self.parse_literal_expression().map(PropertyKey::from)?, + Kind::Str => PropertyKey::from(self.parse_literal_expression()), + kind if kind.is_number() => PropertyKey::from(self.parse_literal_expression()), // { [foo]() {} } Kind::LBrack => { computed = true; - self.parse_computed_property_name().map(PropertyKey::from)? + PropertyKey::from(self.parse_computed_property_name()) } _ => { - let ident = self.parse_identifier_name()?; + let ident = self.parse_identifier_name(); PropertyKey::StaticIdentifier(self.alloc(ident)) } }; - Ok((key, computed)) + (key, computed) } /// `ComputedPropertyName`[Yield, Await] : [ `AssignmentExpression`[+In, ?Yield, ?Await] ] - pub(crate) fn parse_computed_property_name(&mut self) -> Result> { + pub(crate) fn parse_computed_property_name(&mut self) -> Expression<'a> { self.bump_any(); // advance `[` let expression = self.context( Context::In, Context::empty(), Self::parse_assignment_expression_or_higher, - )?; + ); - self.expect(Kind::RBrack)?; - Ok(expression) + self.expect(Kind::RBrack); + expression } /// `PropertyDefinition`[Yield, Await] : /// `MethodDefinition`[?Yield, ?Await] - fn parse_property_definition_method(&mut self) -> Result>> { + fn parse_property_definition_method(&mut self) -> Box<'a, ObjectProperty<'a>> { let span = self.start_span(); let r#async = self.eat(Kind::Async); let generator = self.eat(Kind::Star); - let (key, computed) = self.parse_property_name()?; - let method = self.parse_method(r#async, generator)?; + let (key, computed) = self.parse_property_name(); + let method = self.parse_method(r#async, generator); let value = Expression::FunctionExpression(method); - Ok(self.ast.alloc_object_property( + self.ast.alloc_object_property( self.end_span(span), PropertyKind::Init, key, @@ -223,18 +222,18 @@ impl<'a> ParserImpl<'a> { /* method */ true, /* shorthand */ false, /* computed */ computed, - )) + ) } /// `MethodDefinition`[Yield, Await] : /// get `ClassElementName`[?Yield, ?Await] ( ) { `FunctionBody`[~Yield, ~Await] } - fn parse_method_getter(&mut self) -> Result>> { + fn parse_method_getter(&mut self) -> Box<'a, ObjectProperty<'a>> { let span = self.start_span(); - self.expect(Kind::Get)?; - let (key, computed) = self.parse_property_name()?; - let method = self.parse_method(false, false)?; + self.expect(Kind::Get); + let (key, computed) = self.parse_property_name(); + let method = self.parse_method(false, false); let value = Expression::FunctionExpression(method); - Ok(self.ast.alloc_object_property( + self.ast.alloc_object_property( self.end_span(span), PropertyKind::Get, key, @@ -242,18 +241,18 @@ impl<'a> ParserImpl<'a> { /* method */ false, /* shorthand */ false, /* computed */ computed, - )) + ) } /// `MethodDefinition`[Yield, Await] : /// set `ClassElementName`[?Yield, ?Await] ( `PropertySetParameterList` ) { `FunctionBody`[~Yield, ~Await] } - fn parse_method_setter(&mut self) -> Result>> { + fn parse_method_setter(&mut self) -> Box<'a, ObjectProperty<'a>> { let span = self.start_span(); - self.expect(Kind::Set)?; - let (key, computed) = self.parse_property_name()?; - let method = self.parse_method(false, false)?; + self.expect(Kind::Set); + let (key, computed) = self.parse_property_name(); + let method = self.parse_method(false, false); - Ok(self.ast.alloc_object_property( + self.ast.alloc_object_property( self.end_span(span), PropertyKind::Set, key, @@ -261,6 +260,6 @@ impl<'a> ParserImpl<'a> { /* method */ false, /* shorthand */ false, /* computed */ computed, - )) + ) } } diff --git a/crates/oxc_parser/src/js/statement.rs b/crates/oxc_parser/src/js/statement.rs index 59208fb88acc0..8123209242dcf 100644 --- a/crates/oxc_parser/src/js/statement.rs +++ b/crates/oxc_parser/src/js/statement.rs @@ -1,6 +1,5 @@ use oxc_allocator::{Box, Vec}; use oxc_ast::ast::*; -use oxc_diagnostics::Result; use oxc_span::{Atom, GetSpan, Span}; use super::{VariableDeclarationParent, grammar::CoverGrammar}; @@ -31,7 +30,7 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_directives_and_statements( &mut self, is_top_level: bool, - ) -> Result<(Vec<'a, Directive<'a>>, Vec<'a, Statement<'a>>)> { + ) -> (Vec<'a, Directive<'a>>, Vec<'a, Statement<'a>>) { let mut directives = self.ast.vec(); let mut statements = self.ast.vec(); @@ -40,7 +39,7 @@ impl<'a> ParserImpl<'a> { if !is_top_level && self.at(Kind::RCurly) { break; } - let stmt = self.parse_statement_list_item(StatementContext::StatementList)?; + let stmt = self.parse_statement_list_item(StatementContext::StatementList); if is_top_level { if let Some(module_decl) = stmt.as_module_declaration() { @@ -70,7 +69,7 @@ impl<'a> ParserImpl<'a> { statements.push(stmt); } - Ok((directives, statements)) + (directives, statements) } /// `StatementListItem`[Yield, Await, Return] : @@ -79,14 +78,14 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_statement_list_item( &mut self, stmt_ctx: StatementContext, - ) -> Result> { + ) -> Statement<'a> { let start_span = self.start_span(); let has_no_side_effects_comment = self.lexer.trivia_builder.previous_token_has_no_side_effects_comment(); if self.at(Kind::At) { - self.eat_decorators()?; + self.eat_decorators(); } // For performance reasons, match orders are: @@ -95,7 +94,7 @@ impl<'a> ParserImpl<'a> { // 3. peek token let mut stmt = match self.cur_kind() { Kind::LCurly => self.parse_block_statement(), - Kind::Semicolon => Ok(self.parse_empty_statement()), + Kind::Semicolon => self.parse_empty_statement(), Kind::If => self.parse_if_statement(), Kind::Do => self.parse_do_while_statement(), Kind::While => self.parse_while_statement(), @@ -155,13 +154,13 @@ impl<'a> ParserImpl<'a> { self.parse_ts_declaration_statement(start_span) } _ => self.parse_expression_or_labeled_statement(), - }?; + }; if has_no_side_effects_comment { Self::set_pure_on_function_stmt(&mut stmt); } - Ok(stmt) + stmt } fn set_pure_on_function_stmt(stmt: &mut Statement<'a>) { @@ -200,56 +199,53 @@ impl<'a> ParserImpl<'a> { } } - fn parse_expression_or_labeled_statement(&mut self) -> Result> { + fn parse_expression_or_labeled_statement(&mut self) -> Statement<'a> { let span = self.start_span(); - let expr = self.parse_expr()?; + let expr = self.parse_expr(); if let Expression::Identifier(ident) = &expr { // Section 14.13 Labelled Statement // Avoids lookahead for a labeled statement, which is on a hot path if self.eat(Kind::Colon) { let label = self.ast.label_identifier(ident.span, ident.name); - let body = self.parse_statement_list_item(StatementContext::Label)?; - return Ok(self.ast.statement_labeled(self.end_span(span), label, body)); + let body = self.parse_statement_list_item(StatementContext::Label); + return self.ast.statement_labeled(self.end_span(span), label, body); } } self.parse_expression_statement(span, expr) } /// Section 14.2 Block Statement - pub(crate) fn parse_block(&mut self) -> Result>> { + pub(crate) fn parse_block(&mut self) -> Box<'a, BlockStatement<'a>> { let span = self.start_span(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let mut body = self.ast.vec(); while !self.at(Kind::RCurly) && !self.has_fatal_error() { - let stmt = self.parse_statement_list_item(StatementContext::StatementList)?; + let stmt = self.parse_statement_list_item(StatementContext::StatementList); body.push(stmt); } - self.expect(Kind::RCurly)?; - Ok(self.ast.alloc_block_statement(self.end_span(span), body)) + self.expect(Kind::RCurly); + self.ast.alloc_block_statement(self.end_span(span), body) } - pub(crate) fn parse_block_statement(&mut self) -> Result> { - let block = self.parse_block()?; - Ok(Statement::BlockStatement(block)) + pub(crate) fn parse_block_statement(&mut self) -> Statement<'a> { + let block = self.parse_block(); + Statement::BlockStatement(block) } /// Section 14.3.2 Variable Statement - pub(crate) fn parse_variable_statement( - &mut self, - stmt_ctx: StatementContext, - ) -> Result> { + pub(crate) fn parse_variable_statement(&mut self, stmt_ctx: StatementContext) -> Statement<'a> { let start_span = self.start_span(); let decl = self.parse_variable_declaration( start_span, VariableDeclarationParent::Statement, &Modifiers::empty(), - )?; + ); if stmt_ctx.is_single_statement() && decl.kind.is_lexical() { self.error(diagnostics::lexical_declaration_single_statement(decl.span)); } - Ok(Statement::VariableDeclaration(decl)) + Statement::VariableDeclaration(decl) } /// Section 14.4 Empty Statement @@ -264,46 +260,44 @@ impl<'a> ParserImpl<'a> { &mut self, span: u32, expression: Expression<'a>, - ) -> Result> { - self.asi()?; - Ok(self.ast.statement_expression(self.end_span(span), expression)) + ) -> Statement<'a> { + self.asi(); + self.ast.statement_expression(self.end_span(span), expression) } /// Section 14.6 If Statement - fn parse_if_statement(&mut self) -> Result> { + fn parse_if_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // bump `if` - let test = self.parse_paren_expression()?; - let consequent = self.parse_statement_list_item(StatementContext::If)?; - let alternate = self - .eat(Kind::Else) - .then(|| self.parse_statement_list_item(StatementContext::If)) - .transpose()?; - Ok(self.ast.statement_if(self.end_span(span), test, consequent, alternate)) + let test = self.parse_paren_expression(); + let consequent = self.parse_statement_list_item(StatementContext::If); + let alternate = + self.eat(Kind::Else).then(|| self.parse_statement_list_item(StatementContext::If)); + self.ast.statement_if(self.end_span(span), test, consequent, alternate) } /// Section 14.7.2 Do-While Statement - fn parse_do_while_statement(&mut self) -> Result> { + fn parse_do_while_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // advance `do` - let body = self.parse_statement_list_item(StatementContext::Do)?; - self.expect(Kind::While)?; - let test = self.parse_paren_expression()?; + let body = self.parse_statement_list_item(StatementContext::Do); + self.expect(Kind::While); + let test = self.parse_paren_expression(); self.bump(Kind::Semicolon); - Ok(self.ast.statement_do_while(self.end_span(span), body, test)) + self.ast.statement_do_while(self.end_span(span), body, test) } /// Section 14.7.3 While Statement - fn parse_while_statement(&mut self) -> Result> { + fn parse_while_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // bump `while` - let test = self.parse_paren_expression()?; - let body = self.parse_statement_list_item(StatementContext::While)?; - Ok(self.ast.statement_while(self.end_span(span), test, body)) + let test = self.parse_paren_expression(); + let body = self.parse_statement_list_item(StatementContext::While); + self.ast.statement_while(self.end_span(span), test, body) } /// Section 14.7.4 For Statement - fn parse_for_statement(&mut self) -> Result> { + fn parse_for_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // bump `for` @@ -318,7 +312,7 @@ impl<'a> ParserImpl<'a> { false }; - self.expect(Kind::LParen)?; + self.expect(Kind::LParen); // for (;.. if self.at(Kind::Semicolon) { @@ -349,13 +343,15 @@ impl<'a> ParserImpl<'a> { return self.parse_for_loop(span, None, r#await); } - let init_expression = - self.context(Context::empty(), Context::In, ParserImpl::parse_expr)?; + let init_expression = self.context(Context::empty(), Context::In, ParserImpl::parse_expr); // for (a.b in ...), for ([a] in ..), for ({a} in ..) if self.at(Kind::In) || self.at(Kind::Of) { - let target = AssignmentTarget::cover(init_expression, self) - .map_err(|_| diagnostics::unexpected_token(self.end_span(expr_span)))?; + let target = AssignmentTarget::cover(init_expression, self); + if self.fatal_error.is_some() { + let span = self.end_span(expr_span); + self.fatal_error.as_mut().unwrap().error = diagnostics::unexpected_token(span); + } let for_stmt_left = ForStatementLeft::from(target); if !r#await && is_async_of { self.error(diagnostics::for_loop_async_of(self.end_span(expr_span))); @@ -373,12 +369,12 @@ impl<'a> ParserImpl<'a> { &mut self, span: u32, r#await: bool, - ) -> Result> { + ) -> Statement<'a> { let start_span = self.start_span(); let init_declaration = self.context(Context::empty(), Context::In, |p| { let decl_ctx = VariableDeclarationParent::For; p.parse_variable_declaration(start_span, decl_ctx, &Modifiers::empty()) - })?; + }); // for (.. a in) for (.. a of) if matches!(self.cur_kind(), Kind::In | Kind::Of) { @@ -390,12 +386,8 @@ impl<'a> ParserImpl<'a> { self.parse_for_loop(span, init, r#await) } - fn parse_using_declaration_for_statement( - &mut self, - span: u32, - r#await: bool, - ) -> Result> { - let using_decl = self.parse_using_declaration(StatementContext::For)?; + fn parse_using_declaration_for_statement(&mut self, span: u32, r#await: bool) -> Statement<'a> { + let using_decl = self.parse_using_declaration(StatementContext::For); if matches!(self.cur_kind(), Kind::In) { if using_decl.kind.is_await() { @@ -423,30 +415,30 @@ impl<'a> ParserImpl<'a> { span: u32, init: Option>, r#await: bool, - ) -> Result> { - self.expect(Kind::Semicolon)?; + ) -> Statement<'a> { + self.expect(Kind::Semicolon); if let Some(ForStatementInit::VariableDeclaration(decl)) = &init { for d in &decl.declarations { self.check_missing_initializer(d); } } let test = if !self.at(Kind::Semicolon) && !self.at(Kind::RParen) { - Some(self.context(Context::In, Context::empty(), ParserImpl::parse_expr)?) + Some(self.context(Context::In, Context::empty(), ParserImpl::parse_expr)) } else { None }; - self.expect(Kind::Semicolon)?; + self.expect(Kind::Semicolon); let update = if self.at(Kind::RParen) { None } else { - Some(self.context(Context::In, Context::empty(), ParserImpl::parse_expr)?) + Some(self.context(Context::In, Context::empty(), ParserImpl::parse_expr)) }; - self.expect(Kind::RParen)?; + self.expect(Kind::RParen); if r#await { self.error(diagnostics::for_await(self.end_span(span))); } - let body = self.parse_statement_list_item(StatementContext::For)?; - Ok(self.ast.statement_for(self.end_span(span), init, test, update, body)) + let body = self.parse_statement_list_item(StatementContext::For); + self.ast.statement_for(self.end_span(span), init, test, update, body) } fn parse_for_in_or_of_loop( @@ -454,43 +446,43 @@ impl<'a> ParserImpl<'a> { span: u32, r#await: bool, left: ForStatementLeft<'a>, - ) -> Result> { + ) -> Statement<'a> { let is_for_in = self.at(Kind::In); self.bump_any(); // bump `in` or `of` let right = if is_for_in { self.parse_expr() } else { self.parse_assignment_expression_or_higher() - }?; - self.expect(Kind::RParen)?; + }; + self.expect(Kind::RParen); if r#await && is_for_in { self.error(diagnostics::for_await(self.end_span(span))); } - let body = self.parse_statement_list_item(StatementContext::For)?; + let body = self.parse_statement_list_item(StatementContext::For); let span = self.end_span(span); if is_for_in { - Ok(self.ast.statement_for_in(span, left, right, body)) + self.ast.statement_for_in(span, left, right, body) } else { - Ok(self.ast.statement_for_of(span, r#await, left, right, body)) + self.ast.statement_for_of(span, r#await, left, right, body) } } /// Section 14.8 Continue Statement /// Section 14.9 Break Statement - fn parse_break_or_continue_statement(&mut self) -> Result> { + fn parse_break_or_continue_statement(&mut self) -> Statement<'a> { let span = self.start_span(); let kind = self.cur_kind(); self.bump_any(); // bump `break` or `continue` let label = - if self.can_insert_semicolon() { None } else { Some(self.parse_label_identifier()?) }; - self.asi()?; + if self.can_insert_semicolon() { None } else { Some(self.parse_label_identifier()) }; + self.asi(); let end_span = self.end_span(span); match kind { - Kind::Break => Ok(self.ast.statement_break(end_span, label)), - Kind::Continue => Ok(self.ast.statement_continue(end_span, label)), + Kind::Break => self.ast.statement_break(end_span, label), + Kind::Continue => self.ast.statement_continue(end_span, label), _ => unreachable!(), } } @@ -499,14 +491,14 @@ impl<'a> ParserImpl<'a> { /// `ReturnStatement`[Yield, Await] : /// return ; /// return [no `LineTerminator` here] Expression[+In, ?Yield, ?Await] ; - fn parse_return_statement(&mut self) -> Result> { + fn parse_return_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // advance `return` let argument = if self.eat(Kind::Semicolon) || self.can_insert_semicolon() { None } else { - let expr = self.context(Context::In, Context::empty(), ParserImpl::parse_expr)?; - self.asi()?; + let expr = self.context(Context::In, Context::empty(), ParserImpl::parse_expr); + self.asi(); Some(expr) }; if !self.ctx.has_return() { @@ -515,29 +507,29 @@ impl<'a> ParserImpl<'a> { span + 6, ))); } - Ok(self.ast.statement_return(self.end_span(span), argument)) + self.ast.statement_return(self.end_span(span), argument) } /// Section 14.11 With Statement - fn parse_with_statement(&mut self) -> Result> { + fn parse_with_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // bump `with` - let object = self.parse_paren_expression()?; - let body = self.parse_statement_list_item(StatementContext::With)?; + let object = self.parse_paren_expression(); + let body = self.parse_statement_list_item(StatementContext::With); let span = self.end_span(span); - Ok(self.ast.statement_with(span, object, body)) + self.ast.statement_with(span, object, body) } /// Section 14.12 Switch Statement - fn parse_switch_statement(&mut self) -> Result> { + fn parse_switch_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // advance `switch` - let discriminant = self.parse_paren_expression()?; - let cases = self.parse_normal_list(Kind::LCurly, Kind::RCurly, Self::parse_switch_case)?; - Ok(self.ast.statement_switch(self.end_span(span), discriminant, cases)) + let discriminant = self.parse_paren_expression(); + let cases = self.parse_normal_list(Kind::LCurly, Kind::RCurly, Self::parse_switch_case); + self.ast.statement_switch(self.end_span(span), discriminant, cases) } - pub(crate) fn parse_switch_case(&mut self) -> Result>> { + pub(crate) fn parse_switch_case(&mut self) -> Option> { let span = self.start_span(); let test = match self.cur_kind() { Kind::Default => { @@ -546,24 +538,24 @@ impl<'a> ParserImpl<'a> { } Kind::Case => { self.bump_any(); - let expression = self.parse_expr()?; + let expression = self.parse_expr(); Some(expression) } - _ => return Err(self.unexpected()), + _ => return self.unexpected(), }; - self.expect(Kind::Colon)?; + self.expect(Kind::Colon); let mut consequent = self.ast.vec(); while !matches!(self.cur_kind(), Kind::Case | Kind::Default | Kind::RCurly) && !self.has_fatal_error() { - let stmt = self.parse_statement_list_item(StatementContext::StatementList)?; + let stmt = self.parse_statement_list_item(StatementContext::StatementList); consequent.push(stmt); } - Ok(Some(self.ast.switch_case(self.end_span(span), test, consequent))) + Some(self.ast.switch_case(self.end_span(span), test, consequent)) } /// Section 14.14 Throw Statement - fn parse_throw_statement(&mut self) -> Result> { + fn parse_throw_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // advance `throw` if self.cur_token().is_on_new_line { @@ -573,50 +565,50 @@ impl<'a> ParserImpl<'a> { self.cur_token().span(), )); } - let argument = self.parse_expr()?; - self.asi()?; - Ok(self.ast.statement_throw(self.end_span(span), argument)) + let argument = self.parse_expr(); + self.asi(); + self.ast.statement_throw(self.end_span(span), argument) } /// Section 14.15 Try Statement - fn parse_try_statement(&mut self) -> Result> { + fn parse_try_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); // bump `try` - let block = self.parse_block()?; + let block = self.parse_block(); - let handler = self.at(Kind::Catch).then(|| self.parse_catch_clause()).transpose()?; + let handler = self.at(Kind::Catch).then(|| self.parse_catch_clause()); - let finalizer = self.eat(Kind::Finally).then(|| self.parse_block()).transpose()?; + let finalizer = self.eat(Kind::Finally).then(|| self.parse_block()); if handler.is_none() && finalizer.is_none() { let range = Span::new(block.span.end, block.span.end); self.error(diagnostics::expect_catch_finally(range)); } - Ok(self.ast.statement_try(self.end_span(span), block, handler, finalizer)) + self.ast.statement_try(self.end_span(span), block, handler, finalizer) } - fn parse_catch_clause(&mut self) -> Result>> { + fn parse_catch_clause(&mut self) -> Box<'a, CatchClause<'a>> { let span = self.start_span(); self.bump_any(); // advance `catch` let pattern = if self.eat(Kind::LParen) { - let pattern = self.parse_binding_pattern(false)?; - self.expect(Kind::RParen)?; + let pattern = self.parse_binding_pattern(false); + self.expect(Kind::RParen); Some(pattern) } else { None }; - let body = self.parse_block()?; + let body = self.parse_block(); let param = pattern.map(|pattern| self.ast.catch_parameter(pattern.kind.span(), pattern)); - Ok(self.ast.alloc_catch_clause(self.end_span(span), param, body)) + self.ast.alloc_catch_clause(self.end_span(span), param, body) } /// Section 14.16 Debugger Statement - fn parse_debugger_statement(&mut self) -> Result> { + fn parse_debugger_statement(&mut self) -> Statement<'a> { let span = self.start_span(); self.bump_any(); - self.asi()?; - Ok(self.ast.statement_debugger(self.end_span(span))) + self.asi(); + self.ast.statement_debugger(self.end_span(span)) } } diff --git a/crates/oxc_parser/src/jsx/mod.rs b/crates/oxc_parser/src/jsx/mod.rs index 8665fe9ddd2fb..e429f8501d742 100644 --- a/crates/oxc_parser/src/jsx/mod.rs +++ b/crates/oxc_parser/src/jsx/mod.rs @@ -1,54 +1,53 @@ //! [JSX](https://facebook.github.io/jsx) -use oxc_allocator::{Box, Vec}; +use oxc_allocator::{Box, Dummy, Vec}; use oxc_ast::ast::*; -use oxc_diagnostics::Result; use oxc_span::{Atom, GetSpan, Span}; use crate::{Context, ParserImpl, diagnostics, lexer::Kind}; impl<'a> ParserImpl<'a> { - pub(crate) fn parse_jsx_expression(&mut self) -> Result> { + pub(crate) fn parse_jsx_expression(&mut self) -> Expression<'a> { if self.peek_at(Kind::RAngle) { - self.parse_jsx_fragment(false).map(Expression::JSXFragment) + Expression::JSXFragment(self.parse_jsx_fragment(false)) } else { - self.parse_jsx_element(false).map(Expression::JSXElement) + Expression::JSXElement(self.parse_jsx_element(false)) } } /// `JSXFragment` : /// < > `JSXChildren_opt` < / > - fn parse_jsx_fragment(&mut self, in_jsx_child: bool) -> Result>> { + fn parse_jsx_fragment(&mut self, in_jsx_child: bool) -> Box<'a, JSXFragment<'a>> { let span = self.start_span(); - let opening_fragment = self.parse_jsx_opening_fragment(span)?; - let children = self.parse_jsx_children()?; - let closing_fragment = self.parse_jsx_closing_fragment(in_jsx_child)?; - Ok(self.ast.alloc_jsx_fragment( + let opening_fragment = self.parse_jsx_opening_fragment(span); + let children = self.parse_jsx_children(); + let closing_fragment = self.parse_jsx_closing_fragment(in_jsx_child); + self.ast.alloc_jsx_fragment( self.end_span(span), opening_fragment, closing_fragment, children, - )) + ) } /// <> - fn parse_jsx_opening_fragment(&mut self, span: u32) -> Result { - self.expect(Kind::LAngle)?; - self.expect_jsx_child(Kind::RAngle)?; - Ok(self.ast.jsx_opening_fragment(self.end_span(span))) + fn parse_jsx_opening_fragment(&mut self, span: u32) -> JSXOpeningFragment { + self.expect(Kind::LAngle); + self.expect_jsx_child(Kind::RAngle); + self.ast.jsx_opening_fragment(self.end_span(span)) } /// - fn parse_jsx_closing_fragment(&mut self, in_jsx_child: bool) -> Result { + fn parse_jsx_closing_fragment(&mut self, in_jsx_child: bool) -> JSXClosingFragment { let span = self.start_span(); - self.expect(Kind::LAngle)?; - self.expect(Kind::Slash)?; + self.expect(Kind::LAngle); + self.expect(Kind::Slash); if in_jsx_child { - self.expect_jsx_child(Kind::RAngle)?; + self.expect_jsx_child(Kind::RAngle); } else { - self.expect(Kind::RAngle)?; + self.expect(Kind::RAngle); } - Ok(self.ast.jsx_closing_fragment(self.end_span(span))) + self.ast.jsx_closing_fragment(self.end_span(span)) } /// `JSXElement` : @@ -57,14 +56,14 @@ impl<'a> ParserImpl<'a> { /// `in_jsx_child`: /// used for telling `JSXClosingElement` to parse the next jsx child or not /// true when inside jsx element, false when at top level expression - fn parse_jsx_element(&mut self, in_jsx_child: bool) -> Result>> { + fn parse_jsx_element(&mut self, in_jsx_child: bool) -> Box<'a, JSXElement<'a>> { let span = self.start_span(); - let (opening_element, self_closing) = self.parse_jsx_opening_element(span, in_jsx_child)?; - let children = if self_closing { self.ast.vec() } else { self.parse_jsx_children()? }; + let (opening_element, self_closing) = self.parse_jsx_opening_element(span, in_jsx_child); + let children = if self_closing { self.ast.vec() } else { self.parse_jsx_children() }; let closing_element = if self_closing { None } else { - let closing_element = self.parse_jsx_closing_element(in_jsx_child)?; + let closing_element = self.parse_jsx_closing_element(in_jsx_child); if !Self::jsx_element_name_eq(&opening_element.name, &closing_element.name) { self.error(diagnostics::jsx_element_no_match( opening_element.name.span(), @@ -74,12 +73,7 @@ impl<'a> ParserImpl<'a> { } Some(closing_element) }; - Ok(self.ast.alloc_jsx_element( - self.end_span(span), - opening_element, - closing_element, - children, - )) + self.ast.alloc_jsx_element(self.end_span(span), opening_element, closing_element, children) } /// `JSXOpeningElement` : @@ -88,20 +82,20 @@ impl<'a> ParserImpl<'a> { &mut self, span: u32, in_jsx_child: bool, - ) -> Result<( + ) -> ( Box<'a, JSXOpeningElement<'a>>, bool, // `true` if self-closing - )> { - self.expect(Kind::LAngle)?; - let name = self.parse_jsx_element_name()?; + ) { + self.expect(Kind::LAngle); + let name = self.parse_jsx_element_name(); // for tsx - let type_parameters = if self.is_ts { self.try_parse_type_arguments()? } else { None }; - let attributes = self.parse_jsx_attributes()?; + let type_parameters = if self.is_ts { self.try_parse_type_arguments() } else { None }; + let attributes = self.parse_jsx_attributes(); let self_closing = self.eat(Kind::Slash); if !self_closing || in_jsx_child { - self.expect_jsx_child(Kind::RAngle)?; + self.expect_jsx_child(Kind::RAngle); } else { - self.expect(Kind::RAngle)?; + self.expect(Kind::RAngle); } let elem = self.ast.alloc_jsx_opening_element( self.end_span(span), @@ -109,48 +103,49 @@ impl<'a> ParserImpl<'a> { attributes, type_parameters, ); - Ok((elem, self_closing)) + (elem, self_closing) } - fn parse_jsx_closing_element( - &mut self, - in_jsx_child: bool, - ) -> Result>> { + fn parse_jsx_closing_element(&mut self, in_jsx_child: bool) -> Box<'a, JSXClosingElement<'a>> { let span = self.start_span(); - self.expect(Kind::LAngle)?; - self.expect(Kind::Slash)?; - let name = self.parse_jsx_element_name()?; + self.expect(Kind::LAngle); + self.expect(Kind::Slash); + let name = self.parse_jsx_element_name(); if in_jsx_child { - self.expect_jsx_child(Kind::RAngle)?; + self.expect_jsx_child(Kind::RAngle); } else { - self.expect(Kind::RAngle)?; + self.expect(Kind::RAngle); } - Ok(self.ast.alloc_jsx_closing_element(self.end_span(span), name)) + self.ast.alloc_jsx_closing_element(self.end_span(span), name) } /// `JSXElementName` : /// `JSXIdentifier` /// `JSXNamespacedName` /// `JSXMemberExpression` - fn parse_jsx_element_name(&mut self) -> Result> { + fn parse_jsx_element_name(&mut self) -> JSXElementName<'a> { let span = self.start_span(); - let identifier = self.parse_jsx_identifier()?; + let identifier = self.parse_jsx_identifier(); // if self.eat(Kind::Colon) { - let property = self.parse_jsx_identifier()?; - return Ok(self.ast.jsx_element_name_namespaced_name( + let property = self.parse_jsx_identifier(); + return self.ast.jsx_element_name_namespaced_name( self.end_span(span), identifier, property, - )); + ); } // if self.at(Kind::Dot) { - return self - .parse_jsx_member_expression(span, &identifier) - .map(JSXElementName::MemberExpression); + return JSXElementName::MemberExpression( + self.parse_jsx_member_expression(span, &identifier), + ); + } + + if self.fatal_error.is_some() { + return JSXElementName::dummy(self.ast.allocator); } // References begin with a capital letter, `_` or `$` e.g. ``, `<_foo>`, `<$foo>`. @@ -175,7 +170,7 @@ impl<'a> ParserImpl<'a> { } else { JSXElementName::Identifier(self.alloc(identifier)) }; - Ok(element_name) + element_name } /// `JSXMemberExpression` : @@ -185,7 +180,7 @@ impl<'a> ParserImpl<'a> { &mut self, span: u32, object: &JSXIdentifier<'a>, - ) -> Result>> { + ) -> Box<'a, JSXMemberExpression<'a>> { let mut object = if object.name == "this" { self.ast.jsx_member_expression_object_this_expression(object.span) } else { @@ -195,7 +190,7 @@ impl<'a> ParserImpl<'a> { let mut span = Span::new(span, 0); let mut property = None; - while self.eat(Kind::Dot) && !self.has_fatal_error() { + while self.eat(Kind::Dot) && self.fatal_error.is_none() { // if let Some(prop) = property { object = @@ -203,39 +198,39 @@ impl<'a> ParserImpl<'a> { } // - let ident = self.parse_jsx_identifier()?; + let ident = self.parse_jsx_identifier(); // `` is a syntax error. if ident.name.contains('-') { let error = diagnostics::unexpected_token(ident.span); - return Err(self.set_fatal_error(error)); + return self.fatal_error(error); } property = Some(ident); span = self.end_span(span.start); } if let Some(property) = property { - return Ok(self.ast.alloc_jsx_member_expression( + return self.ast.alloc_jsx_member_expression( self.end_span(span.start), object, property, - )); + ); } - Err(self.unexpected()) + self.unexpected() } /// `JSXChildren` : /// `JSXChild` `JSXChildren_opt` - fn parse_jsx_children(&mut self) -> Result>> { + fn parse_jsx_children(&mut self) -> Vec<'a, JSXChild<'a>> { let mut children = self.ast.vec(); - while !self.has_fatal_error() { - if let Some(child) = self.parse_jsx_child()? { + while self.fatal_error.is_none() { + if let Some(child) = self.parse_jsx_child() { children.push(child); } else { break; } } - Ok(children) + children } /// `JSXChild` : @@ -243,31 +238,31 @@ impl<'a> ParserImpl<'a> { /// `JSXElement` /// `JSXFragment` /// { `JSXChildExpression_opt` } - fn parse_jsx_child(&mut self) -> Result>> { + fn parse_jsx_child(&mut self) -> Option> { match self.cur_kind() { // Ok(None), + Kind::LAngle if self.peek_at(Kind::Slash) => None, // <> open fragment Kind::LAngle if self.peek_at(Kind::RAngle) => { - self.parse_jsx_fragment(true).map(JSXChild::Fragment).map(Some) + Some(JSXChild::Fragment(self.parse_jsx_fragment(true))) } // { - self.parse_jsx_element(true).map(JSXChild::Element).map(Some) + Some(JSXChild::Element(self.parse_jsx_element(true))) } // {...expr} Kind::LCurly if self.peek_at(Kind::Dot3) => { - self.parse_jsx_spread_child().map(JSXChild::Spread).map(Some) + Some(JSXChild::Spread(self.parse_jsx_spread_child())) } // {expr} Kind::LCurly => { - self.parse_jsx_expression_container(/* is_jsx_child */ true) - .map(JSXChild::ExpressionContainer) - .map(Some) + Some(JSXChild::ExpressionContainer( + self.parse_jsx_expression_container(/* is_jsx_child */ true), + )) } // text - Kind::JSXText => Ok(Some(JSXChild::Text(self.parse_jsx_text()))), - _ => Err(self.unexpected()), + Kind::JSXText => Some(JSXChild::Text(self.parse_jsx_text())), + _ => self.unexpected(), } } @@ -275,40 +270,40 @@ impl<'a> ParserImpl<'a> { fn parse_jsx_expression_container( &mut self, in_jsx_child: bool, - ) -> Result>> { + ) -> Box<'a, JSXExpressionContainer<'a>> { let span = self.start_span(); self.bump_any(); // bump `{` let expr = if self.at(Kind::RCurly) { if in_jsx_child { - self.expect_jsx_child(Kind::RCurly) + self.expect_jsx_child(Kind::RCurly); } else { - self.expect(Kind::RCurly) - }?; + self.expect(Kind::RCurly); + } let span = self.end_span(span); // Handle comment between curly braces (ex. `{/* comment */}`) // ^^^^^^^^^^^^^ span let expr = self.ast.jsx_empty_expression(Span::new(span.start + 1, span.end - 1)); JSXExpression::EmptyExpression(expr) } else { - let expr = self.parse_jsx_assignment_expression().map(JSXExpression::from)?; + let expr = JSXExpression::from(self.parse_jsx_assignment_expression()); if in_jsx_child { - self.expect_jsx_child(Kind::RCurly) + self.expect_jsx_child(Kind::RCurly); } else { - self.expect(Kind::RCurly) - }?; + self.expect(Kind::RCurly); + } expr }; - Ok(self.ast.alloc_jsx_expression_container(self.end_span(span), expr)) + self.ast.alloc_jsx_expression_container(self.end_span(span), expr) } - fn parse_jsx_assignment_expression(&mut self) -> Result> { + fn parse_jsx_assignment_expression(&mut self) -> Expression<'a> { self.context(Context::default().and_await(self.ctx.has_await()), self.ctx, |p| { let expr = p.parse_expr(); - if let Ok(Expression::SequenceExpression(seq)) = &expr { + if let Expression::SequenceExpression(seq) = &expr { let error = diagnostics::jsx_expressions_may_not_use_the_comma_operator(seq.span); - return Err(p.set_fatal_error(error)); + return p.fatal_error(error); } expr }) @@ -316,95 +311,96 @@ impl<'a> ParserImpl<'a> { /// `JSXChildExpression` : /// { ... `AssignmentExpression` } - fn parse_jsx_spread_child(&mut self) -> Result>> { + fn parse_jsx_spread_child(&mut self) -> Box<'a, JSXSpreadChild<'a>> { let span = self.start_span(); self.bump_any(); // bump `{` - self.expect(Kind::Dot3)?; - let expr = self.parse_jsx_assignment_expression()?; - self.expect_jsx_child(Kind::RCurly)?; - Ok(self.ast.alloc_jsx_spread_child(self.end_span(span), expr)) + self.expect(Kind::Dot3); + let expr = self.parse_jsx_assignment_expression(); + self.expect_jsx_child(Kind::RCurly); + self.ast.alloc_jsx_spread_child(self.end_span(span), expr) } /// `JSXAttributes` : /// `JSXSpreadAttribute` `JSXAttributes_opt` /// `JSXAttribute` `JSXAttributes_opt` - fn parse_jsx_attributes(&mut self) -> Result>> { + fn parse_jsx_attributes(&mut self) -> Vec<'a, JSXAttributeItem<'a>> { let mut attributes = self.ast.vec(); while !matches!(self.cur_kind(), Kind::LAngle | Kind::RAngle | Kind::Slash) - && !self.has_fatal_error() + && self.fatal_error.is_none() { let attribute = match self.cur_kind() { Kind::LCurly => { - self.parse_jsx_spread_attribute().map(JSXAttributeItem::SpreadAttribute) + JSXAttributeItem::SpreadAttribute(self.parse_jsx_spread_attribute()) } - _ => self.parse_jsx_attribute().map(JSXAttributeItem::Attribute), - }?; + _ => JSXAttributeItem::Attribute(self.parse_jsx_attribute()), + }; attributes.push(attribute); } - Ok(attributes) + attributes } /// `JSXAttribute` : /// `JSXAttributeName` `JSXAttributeInitializer_opt` - fn parse_jsx_attribute(&mut self) -> Result>> { + fn parse_jsx_attribute(&mut self) -> Box<'a, JSXAttribute<'a>> { let span = self.start_span(); - let name = self.parse_jsx_attribute_name()?; + let name = self.parse_jsx_attribute_name(); let value = if self.at(Kind::Eq) { - self.expect_jsx_attribute_value(Kind::Eq)?; - Some(self.parse_jsx_attribute_value()?) + self.expect_jsx_attribute_value(Kind::Eq); + Some(self.parse_jsx_attribute_value()) } else { None }; - Ok(self.ast.alloc_jsx_attribute(self.end_span(span), name, value)) + self.ast.alloc_jsx_attribute(self.end_span(span), name, value) } /// `JSXSpreadAttribute` : /// { ... `AssignmentExpression` } - fn parse_jsx_spread_attribute(&mut self) -> Result>> { + fn parse_jsx_spread_attribute(&mut self) -> Box<'a, JSXSpreadAttribute<'a>> { let span = self.start_span(); self.bump_any(); // bump `{` - self.expect(Kind::Dot3)?; - let argument = self.parse_jsx_assignment_expression()?; - self.expect(Kind::RCurly)?; - Ok(self.ast.alloc_jsx_spread_attribute(self.end_span(span), argument)) + self.expect(Kind::Dot3); + let argument = self.parse_jsx_assignment_expression(); + self.expect(Kind::RCurly); + self.ast.alloc_jsx_spread_attribute(self.end_span(span), argument) } /// `JSXAttributeName` : /// `JSXIdentifier` /// `JSXNamespacedName` - fn parse_jsx_attribute_name(&mut self) -> Result> { + fn parse_jsx_attribute_name(&mut self) -> JSXAttributeName<'a> { let span = self.start_span(); - let identifier = self.parse_jsx_identifier()?; + let identifier = self.parse_jsx_identifier(); if self.eat(Kind::Colon) { - let property = self.parse_jsx_identifier()?; - return Ok(self.ast.jsx_attribute_name_namespaced_name( + let property = self.parse_jsx_identifier(); + return self.ast.jsx_attribute_name_namespaced_name( self.end_span(span), identifier, property, - )); + ); } - Ok(JSXAttributeName::Identifier(self.alloc(identifier))) + JSXAttributeName::Identifier(self.alloc(identifier)) } - fn parse_jsx_attribute_value(&mut self) -> Result> { + fn parse_jsx_attribute_value(&mut self) -> JSXAttributeValue<'a> { match self.cur_kind() { - Kind::Str => self - .parse_literal_string() - .map(|str_lit| JSXAttributeValue::StringLiteral(self.alloc(str_lit))), + Kind::Str => { + let str_lit = self.parse_literal_string(); + JSXAttributeValue::StringLiteral(self.alloc(str_lit)) + } Kind::LCurly => { - let expr = self.parse_jsx_expression_container(/* is_jsx_child */ false)?; - Ok(JSXAttributeValue::ExpressionContainer(expr)) + let expr = self.parse_jsx_expression_container(/* is_jsx_child */ false); + JSXAttributeValue::ExpressionContainer(expr) } Kind::LAngle => { if self.peek_at(Kind::RAngle) { - self.parse_jsx_fragment(false).map(JSXAttributeValue::Fragment) + JSXAttributeValue::Fragment(self.parse_jsx_fragment(false)) } else { - self.parse_jsx_element(false).map(JSXAttributeValue::Element) + JSXAttributeValue::Element(self.parse_jsx_element(false)) } } - _ => Err(self.unexpected()), + _ => self.unexpected(), } } @@ -412,17 +408,17 @@ impl<'a> ParserImpl<'a> { /// `IdentifierStart` /// `JSXIdentifier` `IdentifierPart` /// `JSXIdentifier` [no `WhiteSpace` or Comment here] - - fn parse_jsx_identifier(&mut self) -> Result> { + fn parse_jsx_identifier(&mut self) -> JSXIdentifier<'a> { let span = self.start_span(); if !self.at(Kind::Ident) && !self.cur_kind().is_all_keyword() { - return Err(self.unexpected()); + return self.unexpected(); } // Currently at a valid normal Ident or Keyword, keep on lexing for `-` in `` self.continue_lex_jsx_identifier(); self.bump_any(); let span = self.end_span(span); let name = span.source_text(self.source_text); - Ok(self.ast.jsx_identifier(span, name)) + self.ast.jsx_identifier(span, name) } fn parse_jsx_text(&mut self) -> Box<'a, JSXText<'a>> { diff --git a/crates/oxc_parser/src/lib.rs b/crates/oxc_parser/src/lib.rs index 4f387477f8cf8..1a84be6bb74c7 100644 --- a/crates/oxc_parser/src/lib.rs +++ b/crates/oxc_parser/src/lib.rs @@ -86,12 +86,12 @@ mod lexer; #[doc(hidden)] pub mod lexer; -use oxc_allocator::{Allocator, Box as ArenaBox}; +use oxc_allocator::{Allocator, Box as ArenaBox, Dummy}; use oxc_ast::{ AstBuilder, ast::{Expression, Program}, }; -use oxc_diagnostics::{OxcDiagnostic, Result}; +use oxc_diagnostics::OxcDiagnostic; use oxc_span::{ModuleKind, SourceType, Span}; use oxc_syntax::module_record::ModuleRecord; @@ -429,31 +429,22 @@ impl<'a> ParserImpl<'a> { /// Recoverable errors are stored inside `errors`. #[inline] pub fn parse(mut self) -> ParserReturn<'a> { + let mut program = self.parse_program(); let mut panicked = false; - let mut program = match self.parse_program() { - Ok(program) => program, - Err(error) => { - panicked = true; - if let Some(fatal_error) = self.fatal_error.take() { - if !self.lexer.errors.is_empty() && self.cur_kind().is_eof() { - // Noop - } else { - self.error(fatal_error.error); - } - } else { - self.error(error); - } - self.ast.program( - Span::default(), - self.source_type, - self.source_text, - self.ast.vec(), - None, - self.ast.vec(), - self.ast.vec(), - ) + + if let Some(fatal_error) = self.fatal_error.take() { + panicked = true; + self.errors.truncate(fatal_error.errors_len); + if !self.lexer.errors.is_empty() && self.cur_kind().is_eof() { + // Noop + } else { + self.error(fatal_error.error); } - }; + + program = Program::dummy(self.ast.allocator); + program.source_type = self.source_type; + program.source_text = self.source_text; + } self.check_unfinished_errors(); @@ -508,7 +499,10 @@ impl<'a> ParserImpl<'a> { pub fn parse_expression(mut self) -> std::result::Result, Vec> { // initialize cur_token and prev_token by moving onto the first token self.bump_any(); - let expr = self.parse_expr().map_err(|diagnostic| vec![diagnostic])?; + let expr = self.parse_expr(); + if let Some(FatalError { error, .. }) = self.fatal_error.take() { + return Err(vec![error]); + } self.check_unfinished_errors(); let errors = self.lexer.errors.into_iter().chain(self.errors).collect::>(); if !errors.is_empty() { @@ -518,17 +512,17 @@ impl<'a> ParserImpl<'a> { } #[expect(clippy::cast_possible_truncation)] - fn parse_program(&mut self) -> Result> { + fn parse_program(&mut self) -> Program<'a> { // initialize cur_token and prev_token by moving onto the first token self.bump_any(); let hashbang = self.parse_hashbang(); let (directives, statements) = - self.parse_directives_and_statements(/* is_top_level */ true)?; + self.parse_directives_and_statements(/* is_top_level */ true); let span = Span::new(0, self.source_text.len() as u32); let comments = self.ast.vec_from_iter(self.lexer.trivia_builder.comments.iter().copied()); - Ok(self.ast.program( + self.ast.program( span, self.source_type, self.source_text, @@ -536,7 +530,7 @@ impl<'a> ParserImpl<'a> { hashbang, directives, statements, - )) + ) } fn default_context(source_type: SourceType, options: ParseOptions) -> Context { diff --git a/crates/oxc_parser/src/modifiers.rs b/crates/oxc_parser/src/modifiers.rs index 8a7373622c03d..8b2f62ca4ee02 100644 --- a/crates/oxc_parser/src/modifiers.rs +++ b/crates/oxc_parser/src/modifiers.rs @@ -1,7 +1,7 @@ use bitflags::bitflags; use oxc_allocator::Vec; use oxc_ast::ast::TSAccessibility; -use oxc_diagnostics::{OxcDiagnostic, Result}; +use oxc_diagnostics::OxcDiagnostic; use oxc_span::{GetSpan, SPAN, Span}; use crate::{ @@ -290,7 +290,7 @@ impl std::fmt::Display for ModifierKind { } impl<'a> ParserImpl<'a> { - pub(crate) fn eat_modifiers_before_declaration(&mut self) -> Result> { + pub(crate) fn eat_modifiers_before_declaration(&mut self) -> Modifiers<'a> { let mut flags = ModifierFlags::empty(); let mut modifiers = self.ast.vec(); while self.at_modifier() { @@ -298,12 +298,12 @@ impl<'a> ParserImpl<'a> { let modifier_flags = self.cur_kind().into(); let kind = self.cur_kind(); self.bump_any(); - let modifier = self.modifier(kind, self.end_span(span))?; + let modifier = self.modifier(kind, self.end_span(span)); self.check_for_duplicate_modifiers(flags, &modifier); flags.set(modifier_flags, true); modifiers.push(modifier); } - Ok(Modifiers::new(modifiers, flags)) + Modifiers::new(modifiers, flags) } fn at_modifier(&mut self) -> bool { @@ -342,8 +342,12 @@ impl<'a> ParserImpl<'a> { } } - fn modifier(&mut self, kind: Kind, span: Span) -> Result { - Ok(Modifier { span, kind: kind.try_into().map_err(|()| self.unexpected())? }) + fn modifier(&mut self, kind: Kind, span: Span) -> Modifier { + let modifier_kind = ModifierKind::try_from(kind).unwrap_or_else(|()| { + self.set_unexpected(); + ModifierKind::Abstract // Dummy value + }); + Modifier { span, kind: modifier_kind } } pub(crate) fn parse_modifiers( @@ -433,7 +437,7 @@ impl<'a> ParserImpl<'a> { { return None; } - self.modifier(kind, self.end_span(span)).ok() + Some(self.modifier(kind, self.end_span(span))) } fn next_token_is_open_brace(&mut self) -> bool { @@ -446,7 +450,7 @@ impl<'a> ParserImpl<'a> { && self.try_parse(Self::next_token_can_follow_modifier).is_some() } - fn next_token_can_follow_modifier(&mut self) -> Result<()> { + fn next_token_can_follow_modifier(&mut self) { let b = match self.cur_kind() { Kind::Const => self.peek_at(Kind::Enum), Kind::Export => { @@ -464,14 +468,14 @@ impl<'a> ParserImpl<'a> { } _ => self.next_token_is_on_same_line_and_can_follow_modifier(), }; - if b { Ok(()) } else { Err(self.unexpected()) } + if !b { + self.set_unexpected(); + } } - fn try_next_token_is_on_same_line_and_can_follow_modifier(&mut self) -> Result<()> { - if self.next_token_is_on_same_line_and_can_follow_modifier() { - Ok(()) - } else { - Err(self.unexpected()) + fn try_next_token_is_on_same_line_and_can_follow_modifier(&mut self) { + if !self.next_token_is_on_same_line_and_can_follow_modifier() { + self.set_unexpected(); } } diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index 9466f8301bbb5..cea2a5b207d67 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -1,6 +1,5 @@ use oxc_allocator::Box; use oxc_ast::ast::*; -use oxc_diagnostics::Result; use oxc_span::GetSpan; use crate::{ @@ -17,115 +16,123 @@ impl<'a> ParserImpl<'a> { &mut self, span: u32, modifiers: &Modifiers<'a>, - ) -> Result> { + ) -> Declaration<'a> { self.bump_any(); // bump `enum` - let id = self.parse_binding_identifier()?; - let body = self.parse_ts_enum_body()?; + let id = self.parse_binding_identifier(); + let body = self.parse_ts_enum_body(); let span = self.end_span(span); self.verify_modifiers( modifiers, ModifierFlags::DECLARE | ModifierFlags::CONST, diagnostics::modifier_cannot_be_used_here, ); - Ok(self.ast.declaration_ts_enum( + self.ast.declaration_ts_enum( span, id, body, modifiers.contains_const(), modifiers.contains_declare(), - )) + ) } - pub(crate) fn parse_ts_enum_body(&mut self) -> Result> { + pub(crate) fn parse_ts_enum_body(&mut self) -> TSEnumBody<'a> { let span = self.start_span(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let members = self.parse_delimited_list( Kind::RCurly, Kind::Comma, /* trailing_separator */ true, Self::parse_ts_enum_member, - )?; - self.expect(Kind::RCurly)?; - Ok(self.ast.ts_enum_body(self.end_span(span), members)) + ); + self.expect(Kind::RCurly); + self.ast.ts_enum_body(self.end_span(span), members) } - pub(crate) fn parse_ts_enum_member(&mut self) -> Result> { + pub(crate) fn parse_ts_enum_member(&mut self) -> TSEnumMember<'a> { let span = self.start_span(); - let id = self.parse_ts_enum_member_name()?; + let id = self.parse_ts_enum_member_name(); let initializer = if self.eat(Kind::Eq) { - Some(self.parse_assignment_expression_or_higher()?) + Some(self.parse_assignment_expression_or_higher()) } else { None }; - Ok(self.ast.ts_enum_member(self.end_span(span), id, initializer)) + self.ast.ts_enum_member(self.end_span(span), id, initializer) } - fn parse_ts_enum_member_name(&mut self) -> Result> { + fn parse_ts_enum_member_name(&mut self) -> TSEnumMemberName<'a> { match self.cur_kind() { Kind::Str => { - let literal = self.parse_literal_string()?; - Ok(TSEnumMemberName::String(self.alloc(literal))) + let literal = self.parse_literal_string(); + TSEnumMemberName::String(self.alloc(literal)) } - Kind::LBrack => match self.parse_computed_property_name()? { - Expression::StringLiteral(literal) => Ok(TSEnumMemberName::ComputedString(literal)), + Kind::LBrack => match self.parse_computed_property_name() { + Expression::StringLiteral(literal) => TSEnumMemberName::ComputedString(literal), Expression::TemplateLiteral(template) if template.is_no_substitution_template() => { - Ok(TSEnumMemberName::ComputedTemplateString(template)) + TSEnumMemberName::ComputedTemplateString(template) } Expression::NumericLiteral(literal) => { - Err(diagnostics::enum_member_cannot_have_numeric_name(literal.span())) + let error = diagnostics::enum_member_cannot_have_numeric_name(literal.span()); + self.fatal_error(error) + } + expr => { + let error = + diagnostics::computed_property_names_not_allowed_in_enums(expr.span()); + self.fatal_error(error) } - expr => Err(diagnostics::computed_property_names_not_allowed_in_enums(expr.span())), }, - Kind::NoSubstitutionTemplate | Kind::TemplateHead => Err( - diagnostics::computed_property_names_not_allowed_in_enums(self.cur_token().span()), - ), + Kind::NoSubstitutionTemplate | Kind::TemplateHead => { + let error = diagnostics::computed_property_names_not_allowed_in_enums( + self.cur_token().span(), + ); + self.fatal_error(error) + } kind if kind.is_number() => { - Err(diagnostics::enum_member_cannot_have_numeric_name(self.cur_token().span())) + let error = + diagnostics::enum_member_cannot_have_numeric_name(self.cur_token().span()); + self.fatal_error(error) } _ => { - let ident_name = self.parse_identifier_name()?; - Ok(TSEnumMemberName::Identifier(self.alloc(ident_name))) + let ident_name = self.parse_identifier_name(); + TSEnumMemberName::Identifier(self.alloc(ident_name)) } } } /* ------------------- Annotation ----------------- */ - pub(crate) fn parse_ts_type_annotation( - &mut self, - ) -> Result>>> { + pub(crate) fn parse_ts_type_annotation(&mut self) -> Option>> { if !self.is_ts { - return Ok(None); + return None; } if !self.at(Kind::Colon) { - return Ok(None); + return None; } let span = self.start_span(); self.bump_any(); // bump ':' - let type_annotation = self.parse_ts_type()?; - Ok(Some(self.ast.alloc_ts_type_annotation(self.end_span(span), type_annotation))) + let type_annotation = self.parse_ts_type(); + Some(self.ast.alloc_ts_type_annotation(self.end_span(span), type_annotation)) } pub(crate) fn parse_ts_type_alias_declaration( &mut self, span: u32, modifiers: &Modifiers<'a>, - ) -> Result> { - self.expect(Kind::Type)?; + ) -> Declaration<'a> { + self.expect(Kind::Type); - let id = self.parse_binding_identifier()?; - let params = self.parse_ts_type_parameters()?; - self.expect(Kind::Eq)?; + let id = self.parse_binding_identifier(); + let params = self.parse_ts_type_parameters(); + self.expect(Kind::Eq); let annotation = if self.at(Kind::Intrinsic) && !self.peek_at(Kind::Dot) { let span = self.start_span(); self.bump_any(); self.ast.ts_type_intrinsic_keyword(self.end_span(span)) } else { - self.parse_ts_type()? + self.parse_ts_type() }; - self.asi()?; + self.asi(); let span = self.end_span(span); self.verify_modifiers( @@ -134,13 +141,13 @@ impl<'a> ParserImpl<'a> { diagnostics::modifier_cannot_be_used_here, ); - Ok(self.ast.declaration_ts_type_alias( + self.ast.declaration_ts_type_alias( span, id, params, annotation, modifiers.contains_declare(), - )) + ) } /* --------------------- Interface ------------------------ */ @@ -149,12 +156,12 @@ impl<'a> ParserImpl<'a> { &mut self, span: u32, modifiers: &Modifiers<'a>, - ) -> Result> { - self.expect(Kind::Interface)?; // bump interface - let id = self.parse_binding_identifier()?; - let type_parameters = self.parse_ts_type_parameters()?; - let (extends, _) = self.parse_heritage_clause()?; - let body = self.parse_ts_interface_body()?; + ) -> Declaration<'a> { + self.expect(Kind::Interface); // bump interface + let id = self.parse_binding_identifier(); + let type_parameters = self.parse_ts_type_parameters(); + let (extends, _) = self.parse_heritage_clause(); + let body = self.parse_ts_interface_body(); let extends = extends.map_or_else(|| self.ast.vec(), |e| self.ast.ts_interface_heritages(e)); @@ -164,21 +171,22 @@ impl<'a> ParserImpl<'a> { diagnostics::modifier_cannot_be_used_here, ); - Ok(self.ast.declaration_ts_interface( + self.ast.declaration_ts_interface( self.end_span(span), id, type_parameters, extends, body, modifiers.contains_declare(), - )) + ) } - fn parse_ts_interface_body(&mut self) -> Result>> { + fn parse_ts_interface_body(&mut self) -> Box<'a, TSInterfaceBody<'a>> { let span = self.start_span(); - let body_list = - self.parse_normal_list(Kind::LCurly, Kind::RCurly, Self::parse_ts_type_signature)?; - Ok(self.ast.alloc_ts_interface_body(self.end_span(span), body_list)) + let body_list = self.parse_normal_list(Kind::LCurly, Kind::RCurly, |p| { + Some(Self::parse_ts_type_signature(p)) + }); + self.ast.alloc_ts_interface_body(self.end_span(span), body_list) } pub(crate) fn is_at_interface_declaration(&mut self) -> bool { @@ -189,13 +197,12 @@ impl<'a> ParserImpl<'a> { } } - pub(crate) fn parse_ts_type_signature(&mut self) -> Result>> { + pub(crate) fn parse_ts_type_signature(&mut self) -> TSSignature<'a> { if self.is_at_ts_index_signature_member() { let span = self.start_span(); let modifiers = self.parse_modifiers(false, false, false); - return self - .parse_index_signature_declaration(span, &modifiers) - .map(|sig| Some(TSSignature::TSIndexSignature(self.alloc(sig)))); + let sig = self.parse_index_signature_declaration(span, &modifiers); + return TSSignature::TSIndexSignature(self.alloc(sig)); } match self.cur_kind() { @@ -211,7 +218,6 @@ impl<'a> ParserImpl<'a> { } _ => self.parse_ts_property_or_method_signature_member(), } - .map(Some) } /// Must be at `[ident:` or ` [ident:` @@ -268,13 +274,13 @@ impl<'a> ParserImpl<'a> { /* ----------------------- Namespace & Module ----------------------- */ - fn parse_ts_module_block(&mut self) -> Result>> { + fn parse_ts_module_block(&mut self) -> Box<'a, TSModuleBlock<'a>> { let span = self.start_span(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let (directives, statements) = - self.parse_directives_and_statements(/* is_top_level */ false)?; - self.expect(Kind::RCurly)?; - Ok(self.ast.alloc_ts_module_block(self.end_span(span), directives, statements)) + self.parse_directives_and_statements(/* is_top_level */ false); + self.expect(Kind::RCurly); + self.ast.alloc_ts_module_block(self.end_span(span), directives, statements) } pub(crate) fn parse_ts_namespace_or_module_declaration_body( @@ -282,30 +288,27 @@ impl<'a> ParserImpl<'a> { span: u32, kind: TSModuleDeclarationKind, modifiers: &Modifiers<'a>, - ) -> Result>> { + ) -> Box<'a, TSModuleDeclaration<'a>> { self.verify_modifiers( modifiers, ModifierFlags::DECLARE | ModifierFlags::EXPORT, diagnostics::modifier_cannot_be_used_here, ); let id = match self.cur_kind() { - Kind::Str => self.parse_literal_string().map(TSModuleDeclarationName::StringLiteral), - _ => self.parse_binding_identifier().map(TSModuleDeclarationName::Identifier), - }?; + Kind::Str => TSModuleDeclarationName::StringLiteral(self.parse_literal_string()), + _ => TSModuleDeclarationName::Identifier(self.parse_binding_identifier()), + }; let body = if self.eat(Kind::Dot) { let span = self.start_span(); - let decl = self.parse_ts_namespace_or_module_declaration_body( - span, - kind, - &Modifiers::empty(), - )?; + let decl = + self.parse_ts_namespace_or_module_declaration_body(span, kind, &Modifiers::empty()); Some(TSModuleDeclarationBody::TSModuleDeclaration(decl)) } else if self.at(Kind::LCurly) { - let block = self.parse_ts_module_block()?; + let block = self.parse_ts_module_block(); Some(TSModuleDeclarationBody::TSModuleBlock(block)) } else { - self.asi()?; + self.asi(); None }; @@ -315,89 +318,95 @@ impl<'a> ParserImpl<'a> { diagnostics::modifier_cannot_be_used_here, ); - Ok(self.ast.alloc_ts_module_declaration( + self.ast.alloc_ts_module_declaration( self.end_span(span), id, body, kind, modifiers.contains_declare(), - )) + ) } /* ----------------------- declare --------------------- */ - pub(crate) fn parse_ts_declaration_statement( - &mut self, - start_span: u32, - ) -> Result> { + pub(crate) fn parse_ts_declaration_statement(&mut self, start_span: u32) -> Statement<'a> { let reserved_ctx = self.ctx; - let modifiers = self.eat_modifiers_before_declaration()?; + let modifiers = self.eat_modifiers_before_declaration(); self.ctx = self .ctx .union_ambient_if(modifiers.contains_declare()) .and_await(modifiers.contains_async()); - let result = self.parse_declaration(start_span, &modifiers); + let decl = self.parse_declaration(start_span, &modifiers); self.ctx = reserved_ctx; - result.map(Statement::from) + Statement::from(decl) } pub(crate) fn parse_declaration( &mut self, start_span: u32, modifiers: &Modifiers<'a>, - ) -> Result> { + ) -> Declaration<'a> { match self.cur_kind() { Kind::Namespace => { let kind = TSModuleDeclarationKind::Namespace; self.bump_any(); - self.parse_ts_namespace_or_module_declaration_body(start_span, kind, modifiers) - .map(Declaration::TSModuleDeclaration) + let decl = + self.parse_ts_namespace_or_module_declaration_body(start_span, kind, modifiers); + Declaration::TSModuleDeclaration(decl) } Kind::Module => { let kind = TSModuleDeclarationKind::Module; self.bump_any(); - self.parse_ts_namespace_or_module_declaration_body(start_span, kind, modifiers) - .map(Declaration::TSModuleDeclaration) + let decl = + self.parse_ts_namespace_or_module_declaration_body(start_span, kind, modifiers); + Declaration::TSModuleDeclaration(decl) } Kind::Global => { // declare global { } let kind = TSModuleDeclarationKind::Global; - self.parse_ts_namespace_or_module_declaration_body(start_span, kind, modifiers) - .map(Declaration::TSModuleDeclaration) + let decl = + self.parse_ts_namespace_or_module_declaration_body(start_span, kind, modifiers); + Declaration::TSModuleDeclaration(decl) } Kind::Type => self.parse_ts_type_alias_declaration(start_span, modifiers), Kind::Enum => self.parse_ts_enum_declaration(start_span, modifiers), Kind::Interface if self.is_at_interface_declaration() => { self.parse_ts_interface_declaration(start_span, modifiers) } - Kind::Class => self - .parse_class_declaration(start_span, modifiers) - .map(Declaration::ClassDeclaration), + Kind::Class => { + let decl = self.parse_class_declaration(start_span, modifiers); + Declaration::ClassDeclaration(decl) + } Kind::Import => { self.bump_any(); self.parse_ts_import_equals_declaration(start_span) } - kind if kind.is_variable_declaration() => self - .parse_variable_declaration( + kind if kind.is_variable_declaration() => { + let decl = self.parse_variable_declaration( start_span, VariableDeclarationParent::Statement, modifiers, - ) - .map(Declaration::VariableDeclaration), + ); + Declaration::VariableDeclaration(decl) + } _ if self.at_function_with_async() => { let declare = modifiers.contains(ModifierKind::Declare); if declare { - self.parse_ts_declare_function(start_span, modifiers) - .map(Declaration::FunctionDeclaration) + let decl = self.parse_ts_declare_function(start_span, modifiers); + Declaration::FunctionDeclaration(decl) } else if self.is_ts { - self.parse_ts_function_impl(start_span, FunctionKind::Declaration, modifiers) - .map(Declaration::FunctionDeclaration) + let decl = self.parse_ts_function_impl( + start_span, + FunctionKind::Declaration, + modifiers, + ); + Declaration::FunctionDeclaration(decl) } else { - self.parse_function_impl(FunctionKind::Declaration) - .map(Declaration::FunctionDeclaration) + let decl = self.parse_function_impl(FunctionKind::Declaration); + Declaration::FunctionDeclaration(decl) } } - _ => Err(self.unexpected()), + _ => self.unexpected(), } } @@ -405,11 +414,11 @@ impl<'a> ParserImpl<'a> { &mut self, start_span: u32, modifiers: &Modifiers<'a>, - ) -> Result>> { + ) -> Box<'a, Function<'a>> { let r#async = modifiers.contains(ModifierKind::Async); - self.expect(Kind::Function)?; + self.expect(Kind::Function); let func_kind = FunctionKind::TSDeclaration; - let id = self.parse_function_id(func_kind, r#async, false)?; + let id = self.parse_function_id(func_kind, r#async, false); self.parse_function( start_span, id, @@ -421,80 +430,76 @@ impl<'a> ParserImpl<'a> { ) } - pub(crate) fn parse_ts_type_assertion(&mut self) -> Result> { + pub(crate) fn parse_ts_type_assertion(&mut self) -> Expression<'a> { let span = self.start_span(); - self.expect(Kind::LAngle)?; - let type_annotation = self.parse_ts_type()?; - self.expect(Kind::RAngle)?; + self.expect(Kind::LAngle); + let type_annotation = self.parse_ts_type(); + self.expect(Kind::RAngle); let lhs_span = self.start_span(); - let expression = self.parse_simple_unary_expression(lhs_span)?; - Ok(self.ast.expression_ts_type_assertion(self.end_span(span), expression, type_annotation)) + let expression = self.parse_simple_unary_expression(lhs_span); + self.ast.expression_ts_type_assertion(self.end_span(span), expression, type_annotation) } - pub(crate) fn parse_ts_import_equals_declaration( - &mut self, - span: u32, - ) -> Result> { + pub(crate) fn parse_ts_import_equals_declaration(&mut self, span: u32) -> Declaration<'a> { let import_kind = if !self.peek_at(Kind::Eq) && self.eat(Kind::Type) { ImportOrExportKind::Type } else { ImportOrExportKind::Value }; - let id = self.parse_binding_identifier()?; + let id = self.parse_binding_identifier(); - self.expect(Kind::Eq)?; + self.expect(Kind::Eq); let reference_span = self.start_span(); let module_reference = if self.eat(Kind::Require) { - self.expect(Kind::LParen)?; - let expression = self.parse_literal_string()?; - self.expect(Kind::RParen)?; + self.expect(Kind::LParen); + let expression = self.parse_literal_string(); + self.expect(Kind::RParen); self.ast.ts_module_reference_external_module_reference( self.end_span(reference_span), expression, ) } else { - let type_name = self.parse_ts_type_name()?; + let type_name = self.parse_ts_type_name(); TSModuleReference::from(type_name) }; - self.asi()?; + self.asi(); - Ok(self.ast.declaration_ts_import_equals( + self.ast.declaration_ts_import_equals( self.end_span(span), id, module_reference, import_kind, - )) + ) } - pub(crate) fn parse_ts_this_parameter(&mut self) -> Result> { + pub(crate) fn parse_ts_this_parameter(&mut self) -> TSThisParameter<'a> { let span = self.start_span(); self.parse_class_element_modifiers(true); - self.eat_decorators()?; + self.eat_decorators(); let this_span = self.start_span(); self.bump_any(); let this = self.end_span(this_span); - let type_annotation = self.parse_ts_type_annotation()?; - Ok(self.ast.ts_this_parameter(self.end_span(span), this, type_annotation)) + let type_annotation = self.parse_ts_type_annotation(); + self.ast.ts_this_parameter(self.end_span(span), this, type_annotation) } - pub(crate) fn eat_decorators(&mut self) -> Result<()> { + pub(crate) fn eat_decorators(&mut self) { if !self.at(Kind::At) { - return Ok(()); + return; } let mut decorators = self.ast.vec(); while self.at(Kind::At) { - let decorator = self.parse_decorator()?; + let decorator = self.parse_decorator(); decorators.push(decorator); } self.state.decorators = decorators; - Ok(()) } pub(crate) fn at_start_of_ts_declaration(&mut self) -> bool { diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index cce889f11c753..a01872707a5f6 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -1,6 +1,5 @@ use oxc_allocator::{Box, Vec}; use oxc_ast::{NONE, ast::*}; -use oxc_diagnostics::Result; use oxc_syntax::operator::UnaryOperator; use crate::{ @@ -10,12 +9,12 @@ use crate::{ }; impl<'a> ParserImpl<'a> { - pub(crate) fn parse_ts_type(&mut self) -> Result> { + pub(crate) fn parse_ts_type(&mut self) -> TSType<'a> { if self.is_start_of_function_type_or_constructor_type() { return self.parse_function_or_constructor_type(); } let span = self.start_span(); - let ty = self.parse_union_type_or_higher()?; + let ty = self.parse_union_type_or_higher(); if !self.ctx.has_disallow_conditional_types() && !self.cur_token().is_on_new_line && self.eat(Kind::Extends) @@ -24,48 +23,46 @@ impl<'a> ParserImpl<'a> { Context::DisallowConditionalTypes, Context::empty(), Self::parse_ts_type, - )?; - self.expect(Kind::Question)?; + ); + self.expect(Kind::Question); let true_type = self.context( Context::empty(), Context::DisallowConditionalTypes, Self::parse_ts_type, - )?; - self.expect(Kind::Colon)?; + ); + self.expect(Kind::Colon); let false_type = self.context( Context::empty(), Context::DisallowConditionalTypes, Self::parse_ts_type, - )?; - return Ok(self.ast.ts_type_conditional_type( + ); + return self.ast.ts_type_conditional_type( self.end_span(span), ty, extends_type, true_type, false_type, - )); + ); } - Ok(ty) + ty } - fn parse_function_or_constructor_type(&mut self) -> Result> { + fn parse_function_or_constructor_type(&mut self) -> TSType<'a> { let span = self.start_span(); let r#abstract = self.eat(Kind::Abstract); let is_constructor_type = self.eat(Kind::New); - let type_parameters = self.parse_ts_type_parameters()?; - let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature)?; + let type_parameters = self.parse_ts_type_parameters(); + let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature); let return_type = { let return_type_span = self.start_span(); - let Some(return_type) = - self.parse_return_type(Kind::Arrow, /* is_type */ false)? - else { - return Err(self.unexpected()); + let Some(return_type) = self.parse_return_type(Kind::Arrow, /* is_type */ false) else { + return self.unexpected(); }; self.ast.ts_type_annotation(self.end_span(return_type_span), return_type) }; let span = self.end_span(span); - Ok(if is_constructor_type { + if is_constructor_type { if let Some(this_param) = &this_param { // type Foo = new (this: number) => any; self.error(diagnostics::ts_constructor_this_parameter(this_param.span)); @@ -79,7 +76,7 @@ impl<'a> ParserImpl<'a> { ) } else { self.ast.ts_type_function_type(span, type_parameters, this_param, params, return_type) - }) + } } fn is_start_of_function_type_or_constructor_type(&mut self) -> bool { @@ -126,7 +123,8 @@ impl<'a> ParserImpl<'a> { } 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() { + self.parse_binding_pattern_kind(); + if !self.has_fatal_error() && errors_count == self.errors_count() { return true; } } @@ -135,36 +133,36 @@ impl<'a> ParserImpl<'a> { pub(crate) fn parse_ts_type_parameters( &mut self, - ) -> Result>>> { + ) -> Option>> { if !self.is_ts { - return Ok(None); + return None; } if !self.at(Kind::LAngle) { - return Ok(None); + return None; } let span = self.start_span(); - self.expect(Kind::LAngle)?; + self.expect(Kind::LAngle); let params = self.parse_delimited_list( Kind::RAngle, Kind::Comma, /* trailing_separator */ true, Self::parse_ts_type_parameter, - )?; - self.expect(Kind::RAngle)?; - Ok(Some(self.ast.alloc_ts_type_parameter_declaration(self.end_span(span), params))) + ); + self.expect(Kind::RAngle); + Some(self.ast.alloc_ts_type_parameter_declaration(self.end_span(span), params)) } - pub(crate) fn parse_ts_implements_clause(&mut self) -> Result>> { - self.expect(Kind::Implements)?; - let first = self.parse_ts_implement_name()?; + pub(crate) fn parse_ts_implements_clause(&mut self) -> Vec<'a, TSClassImplements<'a>> { + self.expect(Kind::Implements); + let first = self.parse_ts_implement_name(); let mut implements = self.ast.vec1(first); while self.eat(Kind::Comma) { - implements.push(self.parse_ts_implement_name()?); + implements.push(self.parse_ts_implement_name()); } - Ok(implements) + implements } - pub(crate) fn parse_ts_type_parameter(&mut self) -> Result> { + pub(crate) fn parse_ts_type_parameter(&mut self) -> TSTypeParameter<'a> { let span = self.start_span(); let modifiers = self.parse_modifiers(false, true, false); @@ -174,11 +172,11 @@ impl<'a> ParserImpl<'a> { diagnostics::cannot_appear_on_a_type_parameter, ); - let name = self.parse_binding_identifier()?; - let constraint = self.parse_ts_type_constraint()?; - let default = self.parse_ts_default_type()?; + let name = self.parse_binding_identifier(); + let constraint = self.parse_ts_type_constraint(); + let default = self.parse_ts_default_type(); - Ok(self.ast.ts_type_parameter( + self.ast.ts_type_parameter( self.end_span(span), name, constraint, @@ -186,14 +184,14 @@ impl<'a> ParserImpl<'a> { modifiers.contains(ModifierKind::In), modifiers.contains(ModifierKind::Out), modifiers.contains(ModifierKind::Const), - )) + ) } - fn parse_intersection_type_or_higher(&mut self) -> Result> { + fn parse_intersection_type_or_higher(&mut self) -> TSType<'a> { self.parse_union_type_or_intersection_type(Kind::Amp, Self::parse_type_operator_or_higher) } - fn parse_union_type_or_higher(&mut self) -> Result> { + fn parse_union_type_or_higher(&mut self) -> TSType<'a> { self.parse_union_type_or_intersection_type( Kind::Pipe, Self::parse_intersection_type_or_higher, @@ -204,20 +202,20 @@ impl<'a> ParserImpl<'a> { &mut self, kind: Kind, parse_constituent_type: F, - ) -> Result> + ) -> TSType<'a> where - F: Fn(&mut Self) -> Result>, + F: Fn(&mut Self) -> TSType<'a>, { let span = self.start_span(); let has_leading_operator = self.eat(kind); /* hasLeadingOperator && parseFunctionOrConstructorTypeToError(isUnionType) ||*/ - let mut ty = parse_constituent_type(self)?; + let mut ty = parse_constituent_type(self); if self.at(kind) || has_leading_operator { let mut types = self.ast.vec1(ty); while self.eat(kind) { types.push( /*parseFunctionOrConstructorTypeToError(isUnionType) || */ - parse_constituent_type(self)?, + parse_constituent_type(self), ); } let span = self.end_span(span); @@ -227,10 +225,10 @@ impl<'a> ParserImpl<'a> { _ => unreachable!(), }; } - Ok(ty) + ty } - fn parse_type_operator_or_higher(&mut self) -> Result> { + fn parse_type_operator_or_higher(&mut self) -> TSType<'a> { match self.cur_kind() { Kind::KeyOf => self.parse_type_operator(TSTypeOperatorOperator::Keyof), Kind::Unique => self.parse_type_operator(TSTypeOperatorOperator::Unique), @@ -244,40 +242,40 @@ impl<'a> ParserImpl<'a> { } } - fn parse_type_operator(&mut self, operator: TSTypeOperatorOperator) -> Result> { + fn parse_type_operator(&mut self, operator: TSTypeOperatorOperator) -> TSType<'a> { let span = self.start_span(); self.bump_any(); // bump operator let operator_span = self.end_span(span); - let ty = self.parse_type_operator_or_higher()?; + let ty = self.parse_type_operator_or_higher(); if operator == TSTypeOperatorOperator::Readonly && !matches!(ty, TSType::TSArrayType(_)) && !matches!(ty, TSType::TSTupleType(_)) { self.error(diagnostics::readonly_in_array_or_tuple_type(operator_span)); } - Ok(self.ast.ts_type_type_operator_type(self.end_span(span), operator, ty)) + self.ast.ts_type_type_operator_type(self.end_span(span), operator, ty) } - fn parse_infer_type(&mut self) -> Result> { + fn parse_infer_type(&mut self) -> TSType<'a> { let span = self.start_span(); self.bump_any(); // bump `infer` - let type_parameter = self.parse_type_parameter_of_infer_type()?; - Ok(self.ast.ts_type_infer_type(self.end_span(span), type_parameter)) + let type_parameter = self.parse_type_parameter_of_infer_type(); + self.ast.ts_type_infer_type(self.end_span(span), type_parameter) } - fn parse_type_parameter_of_infer_type(&mut self) -> Result>> { + fn parse_type_parameter_of_infer_type(&mut self) -> Box<'a, TSTypeParameter<'a>> { let span = self.start_span(); - let name = self.parse_binding_identifier()?; + let name = self.parse_binding_identifier(); let constraint = self.try_parse(Self::try_parse_constraint_of_infer_type).unwrap_or(None); let span = self.end_span(span); let ts_type_parameter = self.ast.alloc_ts_type_parameter(span, name, constraint, None, false, false, false); - Ok(ts_type_parameter) + ts_type_parameter } - fn parse_postfix_type_or_higher(&mut self) -> Result> { + fn parse_postfix_type_or_higher(&mut self) -> TSType<'a> { let span = self.start_span(); - let mut ty = self.parse_non_array_type()?; + let mut ty = self.parse_non_array_type(); while !self.cur_token().is_on_new_line { match self.cur_kind() { @@ -292,7 +290,7 @@ impl<'a> ParserImpl<'a> { Kind::Question => { // If next token is start of a type we have a conditional type if self.lookahead(Self::next_token_is_start_of_type) { - return Ok(ty); + return ty; } self.bump_any(); ty = self.ast.ts_type_js_doc_nullable_type( @@ -304,25 +302,25 @@ impl<'a> ParserImpl<'a> { Kind::LBrack => { self.bump_any(); if self.is_start_of_type(/* in_start_of_parameter */ false) { - let index_type = self.parse_ts_type()?; - self.expect(Kind::RBrack)?; + let index_type = self.parse_ts_type(); + self.expect(Kind::RBrack); ty = self.ast.ts_type_indexed_access_type( self.end_span(span), ty, index_type, ); } else { - self.expect(Kind::RBrack)?; + self.expect(Kind::RBrack); ty = self.ast.ts_type_array_type(self.end_span(span), ty); } } - _ => return Ok(ty), + _ => return ty, } } - Ok(ty) + ty } - fn parse_non_array_type(&mut self) -> Result> { + fn parse_non_array_type(&mut self) -> TSType<'a> { match self.cur_kind() { Kind::Any | Kind::Unknown @@ -337,7 +335,7 @@ impl<'a> ParserImpl<'a> { // Parse `null` as `TSNullKeyword` instead of null literal to align with typescript eslint. | Kind::Null => { if let Some(ty) = self.try_parse(Self::parse_keyword_and_no_dot) { - Ok(ty) + ty } else { self.parse_type_reference() } @@ -374,7 +372,7 @@ impl<'a> ParserImpl<'a> { Kind::Void => { let span = self.start_span(); self.bump_any(); - Ok(self.ast.ts_type_void_keyword(self.end_span(span))) + self.ast.ts_type_void_keyword(self.end_span(span)) } Kind::This => { let span = self.start_span(); @@ -383,7 +381,7 @@ impl<'a> ParserImpl<'a> { if self.peek_at(Kind::Is) && !self.peek_token().is_on_new_line { return self.parse_this_type_predicate(this_type); } - Ok(TSType::TSThisType(self.alloc(this_type))) + TSType::TSThisType(self.alloc(this_type)) } Kind::Typeof => { self.parse_type_query() @@ -397,9 +395,7 @@ impl<'a> ParserImpl<'a> { } Kind::LBrack => self.parse_tuple_type(), Kind::LParen => self.parse_parenthesized_type(), - Kind::Import => self.parse_ts_import_type().map( - TSType::TSImportType - ), + Kind::Import => TSType::TSImportType(self.parse_ts_import_type()), Kind::Asserts => { let peek_token = self.peek_token(); if peek_token.kind.is_identifier_name() && !peek_token.is_on_new_line { @@ -413,7 +409,7 @@ impl<'a> ParserImpl<'a> { } } - fn parse_keyword_and_no_dot(&mut self) -> Result> { + fn parse_keyword_and_no_dot(&mut self) -> TSType<'a> { let span = self.start_span(); let ty = match self.cur_kind() { Kind::Any => { @@ -460,12 +456,12 @@ impl<'a> ParserImpl<'a> { self.bump_any(); self.ast.ts_type_null_keyword(self.end_span(span)) } - _ => return Err(self.unexpected()), + _ => return self.unexpected(), }; if self.at(Kind::Dot) { - return Err(self.unexpected()); + return self.unexpected(); } - Ok(ty) + ty } fn is_start_of_type(&mut self, in_start_of_parameter: bool) -> bool { @@ -556,9 +552,9 @@ impl<'a> ParserImpl<'a> { || self.is_start_of_type(!is_js_doc_parameter) } - fn parse_mapped_type(&mut self) -> Result> { + fn parse_mapped_type(&mut self) -> TSType<'a> { let span = self.start_span(); - self.expect(Kind::LCurly)?; + self.expect(Kind::LCurly); let mut readonly = TSMappedTypeModifierOperator::None; if self.eat(Kind::Readonly) { readonly = TSMappedTypeModifierOperator::True; @@ -568,14 +564,14 @@ impl<'a> ParserImpl<'a> { readonly = TSMappedTypeModifierOperator::Minus; } - self.expect(Kind::LBrack)?; + self.expect(Kind::LBrack); let type_parameter_span = self.start_span(); if !self.cur_kind().is_identifier_name() { - return Err(self.unexpected()); + return self.unexpected(); } - let name = self.parse_binding_identifier()?; - self.expect(Kind::In)?; - let constraint = self.parse_ts_type()?; + let name = self.parse_binding_identifier(); + self.expect(Kind::In); + let constraint = self.parse_ts_type(); let type_parameter = self.alloc(self.ast.ts_type_parameter( self.end_span(type_parameter_span), name, @@ -586,8 +582,8 @@ impl<'a> ParserImpl<'a> { false, )); - let name_type = if self.eat(Kind::As) { Some(self.parse_ts_type()?) } else { None }; - self.expect(Kind::RBrack)?; + let name_type = if self.eat(Kind::As) { Some(self.parse_ts_type()) } else { None }; + self.expect(Kind::RBrack); let optional = match self.cur_kind() { Kind::Question => { @@ -596,71 +592,67 @@ impl<'a> ParserImpl<'a> { } Kind::Minus => { self.bump_any(); - self.expect(Kind::Question)?; + self.expect(Kind::Question); TSMappedTypeModifierOperator::Minus } Kind::Plus => { self.bump_any(); - self.expect(Kind::Question)?; + self.expect(Kind::Question); TSMappedTypeModifierOperator::Plus } _ => TSMappedTypeModifierOperator::None, }; - let type_annotation = self.eat(Kind::Colon).then(|| self.parse_ts_type()).transpose()?; + let type_annotation = self.eat(Kind::Colon).then(|| self.parse_ts_type()); self.bump(Kind::Semicolon); - self.expect(Kind::RCurly)?; + self.expect(Kind::RCurly); - Ok(self.ast.ts_type_mapped_type( + self.ast.ts_type_mapped_type( self.end_span(span), type_parameter, name_type, type_annotation, optional, readonly, - )) + ) } - fn parse_type_literal(&mut self) -> Result> { + fn parse_type_literal(&mut self) -> TSType<'a> { let span = self.start_span(); - let member_list = - self.parse_normal_list(Kind::LCurly, Kind::RCurly, Self::parse_ts_type_signature)?; - Ok(self.ast.ts_type_type_literal(self.end_span(span), member_list)) + let member_list = self.parse_normal_list(Kind::LCurly, Kind::RCurly, |p| { + Some(Self::parse_ts_type_signature(p)) + }); + self.ast.ts_type_type_literal(self.end_span(span), member_list) } - fn parse_type_query(&mut self) -> Result> { + fn parse_type_query(&mut self) -> TSType<'a> { let span = self.start_span(); self.bump_any(); // `bump `typeof` let (entity_name, type_arguments) = if self.at(Kind::Import) { - let entity_name = TSTypeQueryExprName::TSImportType(self.parse_ts_import_type()?); + let entity_name = TSTypeQueryExprName::TSImportType(self.parse_ts_import_type()); (entity_name, None) } else { - let entity_name = self.parse_ts_type_name()?; // TODO: parseEntityName + let entity_name = self.parse_ts_type_name(); // TODO: parseEntityName let entity_name = TSTypeQueryExprName::from(entity_name); let type_arguments = if self.cur_token().is_on_new_line { None } else { - self.try_parse_type_arguments()? + self.try_parse_type_arguments() }; (entity_name, type_arguments) }; - Ok(self.ast.ts_type_type_query(self.end_span(span), entity_name, type_arguments)) + self.ast.ts_type_type_query(self.end_span(span), entity_name, type_arguments) } - fn parse_this_type_predicate(&mut self, this_ty: TSThisType) -> Result> { + fn parse_this_type_predicate(&mut self, this_ty: TSThisType) -> TSType<'a> { let span = this_ty.span.start; self.bump_any(); // bump `is` // TODO: this should go through the ast builder. let parameter_name = TSTypePredicateName::This(this_ty); let type_span = self.start_span(); - let ty = self.parse_ts_type()?; + let ty = self.parse_ts_type(); let type_annotation = Some(self.ast.ts_type_annotation(self.end_span(type_span), ty)); - Ok(self.ast.ts_type_type_predicate( - self.end_span(span), - parameter_name, - false, - type_annotation, - )) + self.ast.ts_type_type_predicate(self.end_span(span), parameter_name, false, type_annotation) } fn parse_this_type_node(&mut self) -> TSThisType { @@ -669,23 +661,23 @@ impl<'a> ParserImpl<'a> { self.ast.ts_this_type(self.end_span(span)) } - fn parse_ts_type_constraint(&mut self) -> Result>> { + fn parse_ts_type_constraint(&mut self) -> Option> { if !self.at(Kind::Extends) { - return Ok(None); + return None; } self.bump_any(); - Ok(Some(self.parse_ts_type()?)) + Some(self.parse_ts_type()) } - fn parse_ts_default_type(&mut self) -> Result>> { + fn parse_ts_default_type(&mut self) -> Option> { if !self.at(Kind::Eq) { - return Ok(None); + return None; } self.bump_any(); - Ok(Some(self.parse_ts_type()?)) + Some(self.parse_ts_type()) } - fn parse_template_type(&mut self, tagged: bool) -> Result> { + fn parse_template_type(&mut self, tagged: bool) -> TSType<'a> { let span = self.start_span(); let mut types = self.ast.vec(); let mut quasis = self.ast.vec(); @@ -695,11 +687,10 @@ impl<'a> ParserImpl<'a> { } Kind::TemplateHead => { quasis.push(self.parse_template_element(tagged)); - types.push(self.parse_ts_type()?); + types.push(self.parse_ts_type()); self.re_lex_template_substitution_tail(); - loop { + while self.fatal_error.is_none() { match self.cur_kind() { - Kind::Eof => self.expect(Kind::TemplateTail)?, Kind::TemplateTail => { quasis.push(self.parse_template_element(tagged)); break; @@ -707,8 +698,12 @@ impl<'a> ParserImpl<'a> { Kind::TemplateMiddle => { quasis.push(self.parse_template_element(tagged)); } + Kind::Eof => { + self.expect(Kind::TemplateTail); + break; + } _ => { - types.push(self.parse_ts_type()?); + types.push(self.parse_ts_type()); self.re_lex_template_substitution_tail(); } } @@ -717,128 +712,127 @@ impl<'a> ParserImpl<'a> { _ => unreachable!("parse_template_literal"), } - Ok(self.ast.ts_type_template_literal_type(self.end_span(span), quasis, types)) + self.ast.ts_type_template_literal_type(self.end_span(span), quasis, types) } - fn parse_asserts_type_predicate(&mut self) -> Result> { + fn parse_asserts_type_predicate(&mut self) -> TSType<'a> { let span = self.start_span(); self.bump_any(); // bump `asserts` let parameter_name = if self.at(Kind::This) { TSTypePredicateName::This(self.parse_this_type_node()) } else { - let ident_name = self.parse_identifier_name()?; + let ident_name = self.parse_identifier_name(); TSTypePredicateName::Identifier(self.alloc(ident_name)) }; let mut type_annotation = None; if self.eat(Kind::Is) { let type_span = self.start_span(); - let ty = self.parse_ts_type()?; + let ty = self.parse_ts_type(); type_annotation = Some(self.ast.ts_type_annotation(self.end_span(type_span), ty)); } - Ok(self.ast.ts_type_type_predicate( + self.ast.ts_type_type_predicate( self.end_span(span), parameter_name, /* asserts */ true, type_annotation, - )) + ) } - fn parse_type_reference(&mut self) -> Result> { + fn parse_type_reference(&mut self) -> TSType<'a> { let span = self.start_span(); - let type_name = self.parse_ts_type_name()?; - let type_parameters = self.parse_type_arguments_of_type_reference()?; - Ok(self.ast.ts_type_type_reference(self.end_span(span), type_name, type_parameters)) + let type_name = self.parse_ts_type_name(); + let type_parameters = self.parse_type_arguments_of_type_reference(); + self.ast.ts_type_type_reference(self.end_span(span), type_name, type_parameters) } - fn parse_ts_implement_name(&mut self) -> Result> { + fn parse_ts_implement_name(&mut self) -> TSClassImplements<'a> { let span = self.start_span(); - let type_name = self.parse_ts_type_name()?; - let type_parameters = self.parse_type_arguments_of_type_reference()?; - Ok(self.ast.ts_class_implements(self.end_span(span), type_name, type_parameters)) + let type_name = self.parse_ts_type_name(); + let type_parameters = self.parse_type_arguments_of_type_reference(); + self.ast.ts_class_implements(self.end_span(span), type_name, type_parameters) } - pub(crate) fn parse_ts_type_name(&mut self) -> Result> { + pub(crate) fn parse_ts_type_name(&mut self) -> TSTypeName<'a> { let span = self.start_span(); - let ident = self.parse_identifier_name()?; + let ident = self.parse_identifier_name(); let ident = self.ast.alloc_identifier_reference(ident.span, ident.name); let mut left = TSTypeName::IdentifierReference(ident); while self.eat(Kind::Dot) { - let right = self.parse_identifier_name()?; + let right = self.parse_identifier_name(); left = self.ast.ts_type_name_qualified_name(self.end_span(span), left, right); } - Ok(left) + left } pub(crate) fn try_parse_type_arguments( &mut self, - ) -> Result>>> { + ) -> Option>> { if self.at(Kind::LAngle) { let span = self.start_span(); - self.expect(Kind::LAngle)?; + self.expect(Kind::LAngle); let params = self.parse_delimited_list( Kind::RAngle, Kind::Comma, /* trailing_separator */ true, Self::parse_ts_type, - )?; - self.expect(Kind::RAngle)?; - return Ok(Some( + ); + self.expect(Kind::RAngle); + return Some( self.ast.alloc_ts_type_parameter_instantiation(self.end_span(span), params), - )); + ); } - Ok(None) + None } fn parse_type_arguments_of_type_reference( &mut self, - ) -> Result>>> { + ) -> Option>> { self.re_lex_l_angle(); if !self.cur_token().is_on_new_line && self.re_lex_l_angle() == Kind::LAngle { let span = self.start_span(); - self.expect(Kind::LAngle)?; + self.expect(Kind::LAngle); let params = self.parse_delimited_list( Kind::RAngle, Kind::Comma, /* trailing_separator */ true, Self::parse_ts_type, - )?; - self.expect(Kind::RAngle)?; - return Ok(Some( + ); + self.expect(Kind::RAngle); + return Some( self.ast.alloc_ts_type_parameter_instantiation(self.end_span(span), params), - )); + ); } - Ok(None) + None } pub(crate) fn parse_type_arguments_in_expression( &mut self, - ) -> Result>>> { + ) -> Option>> { if !self.is_ts { - return Ok(None); + return None; } let span = self.start_span(); if self.re_lex_l_angle() != Kind::LAngle { - return Ok(None); + return None; } - self.expect(Kind::LAngle)?; + self.expect(Kind::LAngle); let params = self.parse_delimited_list( Kind::RAngle, Kind::Comma, /* trailing_separator */ true, Self::parse_ts_type, - )?; + ); // `a < b> = c`` is valid but `a < b >= c` is BinaryExpression if matches!(self.re_lex_right_angle(), Kind::GtEq) { - return Err(self.unexpected()); + return self.unexpected(); } self.re_lex_ts_r_angle(); - self.expect(Kind::RAngle)?; + self.expect(Kind::RAngle); if self.can_follow_type_arguments_in_expr() { - return Ok(Some( - self.ast.alloc_ts_type_parameter_instantiation(self.end_span(span), params), - )); + Some(self.ast.alloc_ts_type_parameter_instantiation(self.end_span(span), params)) + } else { + self.unexpected() } - Err(self.unexpected()) } fn can_follow_type_arguments_in_expr(&mut self) -> bool { @@ -853,32 +847,30 @@ impl<'a> ParserImpl<'a> { } } - fn parse_tuple_type(&mut self) -> Result> { + fn parse_tuple_type(&mut self) -> TSType<'a> { let span = self.start_span(); - self.expect(Kind::LBrack)?; + self.expect(Kind::LBrack); let elements = self.parse_delimited_list( Kind::RBrack, Kind::Comma, /* trailing_separator */ true, Self::parse_tuple_element_name_or_tuple_element_type, - )?; - self.expect(Kind::RBrack)?; - Ok(self.ast.ts_type_tuple_type(self.end_span(span), elements)) + ); + self.expect(Kind::RBrack); + self.ast.ts_type_tuple_type(self.end_span(span), elements) } - pub(super) fn parse_tuple_element_name_or_tuple_element_type( - &mut self, - ) -> Result> { + pub(super) fn parse_tuple_element_name_or_tuple_element_type(&mut self) -> TSTupleElement<'a> { if self.lookahead(Self::is_tuple_element_name) { let span = self.start_span(); let dotdotdot = self.eat(Kind::Dot3); let member_span = self.start_span(); - let label = self.parse_identifier_name()?; + let label = self.parse_identifier_name(); let optional = self.eat(Kind::Question); - self.expect(Kind::Colon)?; - let element_type = self.parse_tuple_element_type()?; + self.expect(Kind::Colon); + let element_type = self.parse_tuple_element_type(); let span = self.end_span(span); - return Ok(if dotdotdot { + return if dotdotdot { let type_annotation = self.ast.ts_type_named_tuple_member( self.end_span(member_span), element_type, @@ -895,7 +887,7 @@ impl<'a> ParserImpl<'a> { label, optional, )) - }); + }; } self.parse_tuple_element_type() } @@ -916,37 +908,37 @@ impl<'a> ParserImpl<'a> { self.at(Kind::Question) && self.peek_at(Kind::Colon) } - fn parse_tuple_element_type(&mut self) -> Result> { + fn parse_tuple_element_type(&mut self) -> TSTupleElement<'a> { let span = self.start_span(); if self.eat(Kind::Dot3) { - let ty = self.parse_ts_type()?; - return Ok(self.ast.ts_tuple_element_rest_type(self.end_span(span), ty)); + let ty = self.parse_ts_type(); + return self.ast.ts_tuple_element_rest_type(self.end_span(span), ty); } - let ty = self.parse_ts_type()?; + let ty = self.parse_ts_type(); if let TSType::JSDocNullableType(ty) = ty { if ty.postfix { - Ok(self.ast.ts_tuple_element_optional_type(ty.span, ty.unbox().type_annotation)) + self.ast.ts_tuple_element_optional_type(ty.span, ty.unbox().type_annotation) } else { - Ok(TSTupleElement::JSDocNullableType(ty)) + TSTupleElement::JSDocNullableType(ty) } } else { - Ok(TSTupleElement::from(ty)) + TSTupleElement::from(ty) } } - fn parse_parenthesized_type(&mut self) -> Result> { + fn parse_parenthesized_type(&mut self) -> TSType<'a> { let span = self.start_span(); self.bump_any(); // bump `(` - let ty = self.parse_ts_type()?; - self.expect(Kind::RParen)?; - Ok(if self.options.preserve_parens { + let ty = self.parse_ts_type(); + self.expect(Kind::RParen); + if self.options.preserve_parens { self.ast.ts_type_parenthesized_type(self.end_span(span), ty) } else { ty - }) + } } - fn parse_literal_type_node(&mut self, negative: bool) -> Result> { + fn parse_literal_type_node(&mut self, negative: bool) -> TSType<'a> { let span = self.start_span(); if negative { self.bump_any(); // bump `-` @@ -956,7 +948,7 @@ impl<'a> ParserImpl<'a> { self.parse_template_literal_expression(false) } else { self.parse_literal_expression() - }?; + }; let span = self.end_span(span); let literal = if negative { @@ -971,78 +963,71 @@ impl<'a> ParserImpl<'a> { Expression::BigIntLiteral(literal) => TSLiteral::BigIntLiteral(literal), Expression::StringLiteral(literal) => TSLiteral::StringLiteral(literal), Expression::TemplateLiteral(literal) => TSLiteral::TemplateLiteral(literal), - _ => return Err(self.unexpected()), + _ => return self.unexpected(), } }; - Ok(self.ast.ts_type_literal_type(span, literal)) + self.ast.ts_type_literal_type(span, literal) } - fn parse_ts_import_type(&mut self) -> Result>> { + fn parse_ts_import_type(&mut self) -> Box<'a, TSImportType<'a>> { let span = self.start_span(); - self.expect(Kind::Import)?; - self.expect(Kind::LParen)?; - let argument = self.parse_ts_type()?; + self.expect(Kind::Import); + self.expect(Kind::LParen); + let argument = self.parse_ts_type(); let options = - if self.eat(Kind::Comma) { Some(self.parse_object_expression()?) } else { None }; - self.expect(Kind::RParen)?; - let qualifier = if self.eat(Kind::Dot) { Some(self.parse_ts_type_name()?) } else { None }; - let type_arguments = self.parse_type_arguments_of_type_reference()?; - Ok(self.ast.alloc_ts_import_type( + if self.eat(Kind::Comma) { Some(self.parse_object_expression()) } else { None }; + self.expect(Kind::RParen); + let qualifier = if self.eat(Kind::Dot) { Some(self.parse_ts_type_name()) } else { None }; + let type_arguments = self.parse_type_arguments_of_type_reference(); + self.ast.alloc_ts_import_type( self.end_span(span), argument, options, qualifier, type_arguments, - )) + ) } - fn try_parse_constraint_of_infer_type(&mut self) -> Result>> { + fn try_parse_constraint_of_infer_type(&mut self) -> Option> { if self.eat(Kind::Extends) { let constraint = self.context( Context::DisallowConditionalTypes, Context::empty(), Self::parse_ts_type, - )?; + ); if self.ctx.has_disallow_conditional_types() || !self.at(Kind::Question) { - return Ok(Some(constraint)); + return Some(constraint); } } - Err(self.unexpected()) + self.unexpected() } pub(crate) fn parse_ts_return_type_annotation( &mut self, kind: Kind, is_type: bool, - ) -> Result>>> { + ) -> Option>> { if !self.is_ts { - return Ok(None); + return None; } if !self.at(Kind::Colon) { - return Ok(None); + return None; } let span = self.start_span(); - Ok(self - .parse_return_type(kind, is_type)? - .map(|return_type| self.ast.alloc_ts_type_annotation(self.end_span(span), return_type))) + self.parse_return_type(kind, is_type) + .map(|return_type| self.ast.alloc_ts_type_annotation(self.end_span(span), return_type)) } - fn parse_return_type( - &mut self, - return_kind: Kind, - is_type: bool, - ) -> Result>> { + fn parse_return_type(&mut self, return_kind: Kind, is_type: bool) -> Option> { if self.should_parse_return_type(return_kind, is_type) { - return self - .context( - Context::empty(), - Context::DisallowConditionalTypes, - Self::parse_type_or_type_predicate, - ) - .map(Some); + return Some(self.context( + Context::empty(), + Context::DisallowConditionalTypes, + Self::parse_type_or_type_predicate, + )); } - Ok(None) + None } fn should_parse_return_type(&mut self, return_kind: Kind, _is_type: bool) -> bool { @@ -1063,65 +1048,65 @@ impl<'a> ParserImpl<'a> { false } - fn parse_type_or_type_predicate(&mut self) -> Result> { + fn parse_type_or_type_predicate(&mut self) -> TSType<'a> { let span = self.start_span(); let type_predicate_variable = self.try_parse(Self::parse_type_predicate_prefix); let type_span = self.start_span(); - let ty = self.parse_ts_type()?; + let ty = self.parse_ts_type(); if let Some(parameter_name) = type_predicate_variable { let type_annotation = Some(self.ast.ts_type_annotation(self.end_span(type_span), ty)); - return Ok(self.ast.ts_type_type_predicate( + return self.ast.ts_type_type_predicate( self.end_span(span), parameter_name, false, type_annotation, - )); + ); } - Ok(ty) + ty } - fn parse_type_predicate_prefix(&mut self) -> Result> { + fn parse_type_predicate_prefix(&mut self) -> TSTypePredicateName<'a> { let parameter_name = if self.at(Kind::This) { TSTypePredicateName::This(self.parse_this_type_node()) } else { - let ident_name = self.parse_identifier_name()?; + let ident_name = self.parse_identifier_name(); TSTypePredicateName::Identifier(self.alloc(ident_name)) }; let token = self.cur_token(); if token.kind == Kind::Is && !token.is_on_new_line { self.bump_any(); - return Ok(parameter_name); + return parameter_name; } - Err(self.unexpected()) + self.unexpected() } pub(crate) fn is_next_at_type_member_name(&mut self) -> bool { self.peek_kind().is_literal_property_name() || self.peek_at(Kind::LBrack) } - pub(crate) fn parse_ts_call_signature_member(&mut self) -> Result> { + pub(crate) fn parse_ts_call_signature_member(&mut self) -> TSSignature<'a> { let span = self.start_span(); - let type_parameters = self.parse_ts_type_parameters()?; - let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature)?; - let return_type = self.parse_ts_return_type_annotation(Kind::Colon, false)?; + let type_parameters = self.parse_ts_type_parameters(); + let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature); + let return_type = self.parse_ts_return_type_annotation(Kind::Colon, false); self.parse_type_member_semicolon(); - Ok(self.ast.ts_signature_call_signature_declaration( + self.ast.ts_signature_call_signature_declaration( self.end_span(span), type_parameters, this_param, params, return_type, - )) + ) } - pub(crate) fn parse_ts_getter_signature_member(&mut self) -> Result> { + pub(crate) fn parse_ts_getter_signature_member(&mut self) -> TSSignature<'a> { let span = self.start_span(); - self.expect(Kind::Get)?; - let (key, computed) = self.parse_property_name()?; - let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature)?; - let return_type = self.parse_ts_return_type_annotation(Kind::Colon, false)?; + self.expect(Kind::Get); + let (key, computed) = self.parse_property_name(); + let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature); + let return_type = self.parse_ts_return_type_annotation(Kind::Colon, false); self.parse_type_member_semicolon(); - Ok(self.ast.ts_signature_method_signature( + self.ast.ts_signature_method_signature( self.end_span(span), key, computed, @@ -1131,22 +1116,22 @@ impl<'a> ParserImpl<'a> { this_param, params, return_type, - )) + ) } - pub(crate) fn parse_ts_setter_signature_member(&mut self) -> Result> { + pub(crate) fn parse_ts_setter_signature_member(&mut self) -> TSSignature<'a> { let span = self.start_span(); - self.expect(Kind::Set)?; - let (key, computed) = self.parse_property_name()?; - let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature)?; - let return_type = self.parse_ts_return_type_annotation(Kind::Colon, false)?; + self.expect(Kind::Set); + let (key, computed) = self.parse_property_name(); + let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature); + let return_type = self.parse_ts_return_type_annotation(Kind::Colon, false); self.parse_type_member_semicolon(); if let Some(return_type) = return_type.as_ref() { self.error(diagnostics::a_set_accessor_cannot_have_a_return_type_annotation( return_type.span, )); } - Ok(self.ast.ts_signature_method_signature( + self.ast.ts_signature_method_signature( self.end_span(span), key, computed, @@ -1156,12 +1141,10 @@ impl<'a> ParserImpl<'a> { this_param, params, return_type, - )) + ) } - pub(crate) fn parse_ts_property_or_method_signature_member( - &mut self, - ) -> Result> { + pub(crate) fn parse_ts_property_or_method_signature_member(&mut self) -> TSSignature<'a> { let span = self.start_span(); let readonly = self.at(Kind::Readonly) && self.is_next_at_type_member_name(); @@ -1169,18 +1152,18 @@ impl<'a> ParserImpl<'a> { self.bump_any(); } - let (key, computed) = self.parse_property_name()?; + let (key, computed) = self.parse_property_name(); let optional = self.eat(Kind::Question); if self.at(Kind::LParen) || self.at(Kind::LAngle) { let TSSignature::TSCallSignatureDeclaration(call_signature) = - self.parse_ts_call_signature_member()? + self.parse_ts_call_signature_member() else { unreachable!() }; self.parse_type_member_semicolon(); let call_signature = call_signature.unbox(); - Ok(self.ast.ts_signature_method_signature( + self.ast.ts_signature_method_signature( self.end_span(span), key, computed, @@ -1190,68 +1173,68 @@ impl<'a> ParserImpl<'a> { call_signature.this_param, call_signature.params, call_signature.return_type, - )) + ) } else { - let type_annotation = self.parse_ts_type_annotation()?; + let type_annotation = self.parse_ts_type_annotation(); self.parse_type_member_semicolon(); - Ok(self.ast.ts_signature_property_signature( + self.ast.ts_signature_property_signature( self.end_span(span), computed, optional, readonly, key, type_annotation, - )) + ) } } - pub(crate) fn parse_ts_constructor_signature_member(&mut self) -> Result> { + pub(crate) fn parse_ts_constructor_signature_member(&mut self) -> TSSignature<'a> { let span = self.start_span(); - self.expect(Kind::New)?; + self.expect(Kind::New); - let type_parameters = self.parse_ts_type_parameters()?; - let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature)?; + let type_parameters = self.parse_ts_type_parameters(); + let (this_param, params) = self.parse_formal_parameters(FormalParameterKind::Signature); if let Some(this_param) = this_param { // interface Foo { new(this: number): Foo } self.error(diagnostics::ts_constructor_this_parameter(this_param.span)); } - let return_type = self.parse_ts_return_type_annotation(Kind::Colon, false)?; + let return_type = self.parse_ts_return_type_annotation(Kind::Colon, false); self.parse_type_member_semicolon(); - Ok(self.ast.ts_signature_construct_signature_declaration( + self.ast.ts_signature_construct_signature_declaration( self.end_span(span), type_parameters, params, return_type, - )) + ) } pub(crate) fn parse_index_signature_declaration( &mut self, span: u32, modifiers: &Modifiers<'a>, - ) -> Result> { + ) -> TSIndexSignature<'a> { self.verify_modifiers( modifiers, ModifierFlags::READONLY | ModifierFlags::STATIC, diagnostics::cannot_appear_on_an_index_signature, ); self.bump(Kind::LBrack); - let parameters = self.ast.vec1(self.parse_ts_index_signature_name()?); - self.expect(Kind::RBrack)?; - let Some(type_annotation) = self.parse_ts_type_annotation()? else { - return Err(self.unexpected()); + let parameters = self.ast.vec1(self.parse_ts_index_signature_name()); + self.expect(Kind::RBrack); + let Some(type_annotation) = self.parse_ts_type_annotation() else { + return self.unexpected(); }; self.parse_type_member_semicolon(); - Ok(self.ast.ts_index_signature( + self.ast.ts_index_signature( self.end_span(span), parameters, type_annotation, modifiers.contains(ModifierKind::Readonly), modifiers.contains(ModifierKind::Static), - )) + ) } fn parse_type_member_semicolon(&mut self) { @@ -1264,16 +1247,16 @@ impl<'a> ParserImpl<'a> { self.bump(Kind::Semicolon); } - fn parse_ts_index_signature_name(&mut self) -> Result> { + fn parse_ts_index_signature_name(&mut self) -> TSIndexSignatureName<'a> { let span = self.start_span(); - let name = self.parse_identifier_name()?.name; - let type_annotation = self.parse_ts_type_annotation()?; + let name = self.parse_identifier_name().name; + let type_annotation = self.parse_ts_type_annotation(); if type_annotation.is_none() { - return Err(self.unexpected()); + return self.unexpected(); } - Ok(self.ast.ts_index_signature_name(self.end_span(span), name, type_annotation.unwrap())) + self.ast.ts_index_signature_name(self.end_span(span), name, type_annotation.unwrap()) } pub(crate) fn parse_class_element_modifiers( @@ -1311,32 +1294,28 @@ impl<'a> ParserImpl<'a> { Modifiers::new(modifiers, flags) } - fn parse_js_doc_unknown_or_nullable_type(&mut self) -> Result> { + fn parse_js_doc_unknown_or_nullable_type(&mut self) -> TSType<'a> { let span = self.start_span(); self.bump_any(); // bump `?` if matches!( self.cur_kind(), Kind::Comma | Kind::RCurly | Kind::RParen | Kind::RAngle | Kind::Eq | Kind::Pipe ) { - return Ok(self.ast.ts_type_js_doc_unknown_type(self.end_span(span))); + return self.ast.ts_type_js_doc_unknown_type(self.end_span(span)); } - let type_annotation = self.parse_ts_type()?; - Ok(self.ast.ts_type_js_doc_nullable_type( + let type_annotation = self.parse_ts_type(); + self.ast.ts_type_js_doc_nullable_type( self.end_span(span), type_annotation, /* postfix */ false, - )) + ) } - fn parse_js_doc_non_nullable_type(&mut self) -> Result> { + fn parse_js_doc_non_nullable_type(&mut self) -> TSType<'a> { let span = self.start_span(); self.bump_any(); // bump `!` - let ty = self.parse_non_array_type()?; - Ok(self.ast.ts_type_js_doc_non_nullable_type( - self.end_span(span), - ty, - /* postfix */ false, - )) + let ty = self.parse_non_array_type(); + self.ast.ts_type_js_doc_non_nullable_type(self.end_span(span), ty, /* postfix */ false) } fn is_binary_operator(&self) -> bool { diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index 7d3dad3ca0e94..845e354ce9296 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -1,8 +1,8 @@ commit: 578ac4df parser_babel Summary: -AST Parsed : 2303/2322 (99.18%) -Positive Passed: 2282/2322 (98.28%) +AST Parsed : 2306/2322 (99.31%) +Positive Passed: 2285/2322 (98.41%) Negative Passed: 1557/1673 (93.07%) Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/categorized/invalid-startindex-and-startline-specified-without-startcolumn/input.js @@ -254,21 +254,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/core/o ╰──── help: new.target is only allowed in constructors and functions invoked using thew `new` operator -Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-identifier-in-property-in-arguments-of-async-call/input.js - - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-identifier-in-property-in-arguments-of-async-call/input.js:1:31] - 1 │ async( x = class { #x = await }); - · ─ - ╰──── - Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-in-private-property-in-params-of-async-arrow/input.js - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-in-private-property-in-params-of-async-arrow/input.js:1:31] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-private-properties/await-in-private-property-in-params-of-async-arrow/input.js:1:33] 1 │ async( x = class { #x = await }) => {} - · ─ + · ▲ ╰──── + help: Try insert a semicolon here Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/arguments-in-key/input.js @@ -280,29 +273,14 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022 4 │ } ╰──── -Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-identifier-in-computed-property-in-arguments-of-async-call/input.js - - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-identifier-in-computed-property-in-arguments-of-async-call/input.js:1:26] - 1 │ async( x = class { [await] = x }) - · ─ - ╰──── - -Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-identifier-in-property-in-arguments-of-async-call/input.js - - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-identifier-in-property-in-arguments-of-async-call/input.js:1:30] - 1 │ async( x = class { x = await }); - · ─ - ╰──── - Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-property-in-params-of-async-arrow/input.js - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-property-in-params-of-async-arrow/input.js:1:30] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-property-in-params-of-async-arrow/input.js:1:32] 1 │ async( x = class { x = await }) => {} - · ─ + · ▲ ╰──── + help: Try insert a semicolon here Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/new-target/input.js @@ -1696,34 +1674,16 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc 1 │ 3e ╰──── - × Invalid Number invalid float - ╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/349/input.js:1:1] - 1 │ 3e - · ── - ╰──── - × Unexpected end of file ╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/350/input.js:1:4] 1 │ 3e+ ╰──── - × Invalid Number invalid float - ╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/350/input.js:1:1] - 1 │ 3e+ - · ─── - ╰──── - × Unexpected end of file ╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/351/input.js:1:4] 1 │ 3e- ╰──── - × Invalid Number invalid float - ╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/351/input.js:1:1] - 1 │ 3e- - · ─── - ╰──── - × Invalid characters after number ╭─[babel/packages/babel-parser/test/fixtures/core/uncategorised/352/input.js:1:2] 1 │ 3x @@ -5718,11 +5678,26 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc ╰──── help: Try insert a semicolon here - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2017/async-functions/multiple-await-in-async-arrow-params/input.js:1:22] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[babel/packages/babel-parser/test/fixtures/es2017/async-functions/multiple-await-in-async-arrow-params/input.js:1:41] 1 │ async ({ x = [ await ], y = { await } }) => {} - · ─ + · ▲ + ╰──── + help: Try insert a semicolon here + + × Invalid assignment in object literal + ╭─[babel/packages/babel-parser/test/fixtures/es2017/async-functions/multiple-await-in-async-arrow-params/input.js:1:10] + 1 │ async ({ x = [ await ], y = { await } }) => {} + · ───────────── + ╰──── + help: Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern. + + × Invalid assignment in object literal + ╭─[babel/packages/babel-parser/test/fixtures/es2017/async-functions/multiple-await-in-async-arrow-params/input.js:1:25] + 1 │ async ({ x = [ await ], y = { await } }) => {} + · ───────────── ╰──── + help: Did you mean to use a ':'? An '=' can only follow a property name when the containing object literal is part of a destructuring pattern. × Line terminator not permitted before arrow ╭─[babel/packages/babel-parser/test/fixtures/es2017/async-functions/newline-before-arrow/input.js:2:1] @@ -8448,11 +8423,12 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc ╰──── help: Try insert a semicolon here - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-computed-property-in-params-of-async-arrow/input.js:1:26] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/await-in-computed-property-in-params-of-async-arrow/input.js:1:34] 1 │ async( x = class { [await] = x }) => {} - · ─ + · ▲ ╰──── + help: Try insert a semicolon here × Unexpected new.target expression ╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/new-target-invalid/input.js:1:9] @@ -9815,12 +9791,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ▲ ╰──── - × Invalid Number invalid float - ╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0004/input.js:1:1] - 1 │ 3e - · ── - ╰──── - × Invalid Character ` │ ` ╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0005/input.js:1:4] @@ -9828,12 +9798,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ▲ ╰──── - × Invalid Number invalid float - ╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0005/input.js:1:1] - 1 │ 3e+ - · ─── - ╰──── - × Invalid Character ` │ ` ╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0006/input.js:1:4] @@ -9841,12 +9805,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ▲ ╰──── - × Invalid Number invalid float - ╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0006/input.js:1:1] - 1 │ 3e- - · ─── - ╰──── - × Invalid characters after number ╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0007/input.js:1:2] 1 │ 3x diff --git a/tasks/coverage/snapshots/parser_test262.snap b/tasks/coverage/snapshots/parser_test262.snap index 35be6915eaee6..649051e34d0ef 100644 --- a/tasks/coverage/snapshots/parser_test262.snap +++ b/tasks/coverage/snapshots/parser_test262.snap @@ -2670,13 +2670,6 @@ Negative Passed: 4519/4519 (100.00%) · ── ╰──── - × Invalid Unicode escape sequence - ╭─[test262/test/language/comments/hashbang/escaped-bang-041.js:1:3] - 1 │ #\041 - · ─ - 2 │ - ╰──── - × Expected `in` but found `throw` ╭─[test262/test/language/comments/hashbang/escaped-bang-041.js:20:1] 19 │ @@ -2685,13 +2678,6 @@ Negative Passed: 4519/4519 (100.00%) · ╰── `in` expected ╰──── - × Invalid Character `!` - ╭─[test262/test/language/comments/hashbang/escaped-bang-u0021.js:1:8] - 1 │ #\u0021 - · ▲ - 2 │ - ╰──── - × Expected `in` but found `throw` ╭─[test262/test/language/comments/hashbang/escaped-bang-u0021.js:20:1] 19 │ @@ -2700,13 +2686,6 @@ Negative Passed: 4519/4519 (100.00%) · ╰── `in` expected ╰──── - × Invalid Character `!` - ╭─[test262/test/language/comments/hashbang/escaped-bang-u21.js:1:8] - 1 │ #\u{21} - · ▲ - 2 │ - ╰──── - × Expected `in` but found `throw` ╭─[test262/test/language/comments/hashbang/escaped-bang-u21.js:20:1] 19 │ @@ -2715,13 +2694,6 @@ Negative Passed: 4519/4519 (100.00%) · ╰── `in` expected ╰──── - × Invalid Unicode escape sequence - ╭─[test262/test/language/comments/hashbang/escaped-bang-x21.js:1:3] - 1 │ #\x21 - · ─ - 2 │ - ╰──── - × Expected `in` but found `throw` ╭─[test262/test/language/comments/hashbang/escaped-bang-x21.js:20:1] 19 │ @@ -6675,12 +6647,13 @@ Negative Passed: 4519/4519 (100.00%) 18 │ ╰──── - × Unexpected token - ╭─[test262/test/language/expressions/async-arrow-function/early-errors-arrow-await-in-formals-default.js:15:16] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[test262/test/language/expressions/async-arrow-function/early-errors-arrow-await-in-formals-default.js:15:17] 14 │ $DONOTEVALUATE(); 15 │ async(x = await) => { } - · ─ + · ▲ ╰──── + help: Try insert a semicolon here × Cannot use `await` as an identifier in an async context ╭─[test262/test/language/expressions/async-arrow-function/early-errors-arrow-await-in-formals.js:15:7] @@ -34291,11 +34264,11 @@ Negative Passed: 4519/4519 (100.00%) · ───── ╰──── - × Spread must be last element - ╭─[test262/test/language/statements/for-in/dstr/array-rest-before-element.js:33:7] + × Unexpected token + ╭─[test262/test/language/statements/for-in/dstr/array-rest-before-element.js:33:6] 32 │ 33 │ for ([...x, y] in [[]]) ; - · ──── + · ───────── ╰──── × Unexpected trailing comma after rest element @@ -34305,11 +34278,11 @@ Negative Passed: 4519/4519 (100.00%) · ─ ╰──── - × Spread must be last element - ╭─[test262/test/language/statements/for-in/dstr/array-rest-before-rest.js:33:7] + × Unexpected token + ╭─[test262/test/language/statements/for-in/dstr/array-rest-before-rest.js:33:6] 32 │ 33 │ for ([...x, ...y] in [[]]) ; - · ──── + · ──────────── ╰──── × Unexpected trailing comma after rest element @@ -34797,11 +34770,11 @@ Negative Passed: 4519/4519 (100.00%) · ───── ╰──── - × Spread must be last element - ╭─[test262/test/language/statements/for-of/dstr/array-rest-before-element.js:33:7] + × Unexpected token + ╭─[test262/test/language/statements/for-of/dstr/array-rest-before-element.js:33:6] 32 │ 33 │ for ([...x, y] of [[]]) ; - · ──── + · ───────── ╰──── × Unexpected trailing comma after rest element @@ -34811,11 +34784,11 @@ Negative Passed: 4519/4519 (100.00%) · ─ ╰──── - × Spread must be last element - ╭─[test262/test/language/statements/for-of/dstr/array-rest-before-rest.js:33:7] + × Unexpected token + ╭─[test262/test/language/statements/for-of/dstr/array-rest-before-rest.js:33:6] 32 │ 33 │ for ([...x, ...y] of [[]]) ; - · ──── + · ──────────── ╰──── × Unexpected trailing comma after rest element diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index b23e476e32bd4..8a5e3d4b751f4 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -12316,12 +12316,11 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private ╰──── help: Try insert a semicolon here - × Expected `<` but found `EOF` + × Unexpected token ╭─[typescript/tests/cases/compiler/errorSpanForUnclosedJsxTag.tsx:11:18] 10 │ 11 │ let y = < Baz >Hello - · ──┬── - · ╰── `<` expected + · ───── ╰──── × 'with' statements are not allowed @@ -13221,6 +13220,15 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private · ─── ╰──── + × Duplicated default export + ╭─[typescript/tests/cases/compiler/jsFileCompilationBindMultipleDefaultExports.ts:1:8] + 1 │ export default class a { + · ─────── + 2 │ } + 3 │ export default var a = 10; + · ─────── + ╰──── + × The keyword 'let' is reserved ╭─[typescript/tests/cases/compiler/jsFileCompilationBindStrictModeErrors.ts:7:5] 6 │ }; @@ -15199,14 +15207,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 2 │ } ╰──── - × Expected `{` but found `Unknown` - ╭─[typescript/tests/cases/compiler/parseErrorInHeritageClause1.ts:1:19] - 1 │ class C extends A ¬ { - · ┬ - · ╰── `{` expected - 2 │ } - ╰──── - × Unexpected token ╭─[typescript/tests/cases/compiler/parseErrorIncorrectReturnToken.ts:2:17] 1 │ type F1 = { @@ -15434,20 +15434,18 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private · ─ ╰──── - × Expected `<` but found `EOF` + × Unexpected token ╭─[typescript/tests/cases/compiler/parseUnaryExpressionNoTypeAssertionInJsx1.ts:2:21] 1 │ const x = "oops"; 2 │ const y = + x; - · ─┬─ - · ╰── `<` expected + · ─── ╰──── - × Expected `<` but found `EOF` + × Unexpected token ╭─[typescript/tests/cases/compiler/parseUnaryExpressionNoTypeAssertionInJsx2.ts:2:15] 1 │ const x = "oops"; 2 │ const y = + <> x; - · ─┬─ - · ╰── `<` expected + · ─── ╰──── × Unexpected token @@ -17741,6 +17739,13 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 5 │ f `123qdawdrqw${ ╰──── + × Unterminated string + ╭─[typescript/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts:5:20] + 4 │ // Incomplete call, enough parameters. + 5 │ f `123qdawdrqw${ }${ + · ─ + ╰──── + × Unexpected token ╭─[typescript/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions2.ts:5:18] 4 │ // Incomplete call, enough parameters. @@ -17754,6 +17759,13 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 5 │ f `123qdawdrqw${ 1 }${ ╰──── + × Unterminated string + ╭─[typescript/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts:5:27] + 4 │ // Incomplete call, but too many parameters. + 5 │ f `123qdawdrqw${ 1 }${ }${ + · ─ + ╰──── + × Unexpected token ╭─[typescript/tests/cases/compiler/taggedTemplatesWithIncompleteTemplateExpressions4.ts:5:24] 4 │ // Incomplete call, but too many parameters. @@ -18419,12 +18431,13 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 2 │ } ╰──── - × Unexpected token - ╭─[typescript/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts:1:27] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[typescript/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction6_es2017.ts:1:28] 1 │ var foo = async (a = await): Promise => { - · ─ + · ▲ 2 │ } ╰──── + help: Try insert a semicolon here × Unexpected token ╭─[typescript/tests/cases/conformance/async/es2017/asyncArrowFunction/asyncArrowFunction7_es2017.ts:3:29] @@ -18507,12 +18520,13 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 2 │ } ╰──── - × Unexpected token - ╭─[typescript/tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction6_es5.ts:1:27] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[typescript/tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction6_es5.ts:1:28] 1 │ var foo = async (a = await): Promise => { - · ─ + · ▲ 2 │ } ╰──── + help: Try insert a semicolon here × Unexpected token ╭─[typescript/tests/cases/conformance/async/es5/asyncArrowFunction/asyncArrowFunction7_es5.ts:3:29] @@ -18648,12 +18662,13 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 2 │ } ╰──── - × Unexpected token - ╭─[typescript/tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction6_es6.ts:1:27] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[typescript/tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction6_es6.ts:1:28] 1 │ var foo = async (a = await): Promise => { - · ─ + · ▲ 2 │ } ╰──── + help: Try insert a semicolon here × Unexpected token ╭─[typescript/tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction7_es6.ts:3:29] @@ -21585,11 +21600,12 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private · ─ ╰──── - × Unexpected token - ╭─[typescript/tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments6_es6.ts:1:11] + × Expected a semicolon or an implicit semicolon after a statement, but found none + ╭─[typescript/tests/cases/conformance/es6/functionPropertyAssignments/FunctionPropertyAssignments6_es6.ts:1:17] 1 │ var v = { *() { } } - · ─ + · ▲ ╰──── + help: Try insert a semicolon here × Unexpected token ╭─[typescript/tests/cases/conformance/es6/memberFunctionDeclarations/MemberFunctionDeclaration4_es6.ts:2:5] @@ -25904,15 +25920,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 3 │ return; ╰──── - × Expected `}` but found `Unknown` - ╭─[typescript/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block2.ts:2:5] - 1 │ function f() { - 2 │ ¬ - · ┬ - · ╰── `}` expected - 3 │ return; - ╰──── - × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[typescript/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Blocks/parserErrorRecovery_Block3.ts:4:12] 3 │ @@ -25948,15 +25955,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 3 │ class C { ╰──── - × Expected `}` but found `Unknown` - ╭─[typescript/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/ClassElements/parserErrorRecovery_ClassElement3.ts:2:4] - 1 │ module M { - 2 │ ¬ - · ┬ - · ╰── `}` expected - 3 │ class C { - ╰──── - × Empty parenthesized expression ╭─[typescript/tests/cases/conformance/parser/ecmascript5/ErrorRecovery/Expressions/parserErrorRecovery_Expression1.ts:1:9] 1 │ var v = ()({}); @@ -27233,11 +27231,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private 1 │ foo(a, \ ╰──── - × Invalid Unicode escape sequence - ╭─[typescript/tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens18.ts:1:8] - 1 │ foo(a \ - ╰──── - × Expected `,` but found `Identifier` ╭─[typescript/tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens18.ts:1:7] 1 │ foo(a \ @@ -27263,11 +27256,6 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/salsa/private · ─ ╰──── - × Invalid Unicode escape sequence - ╭─[typescript/tests/cases/conformance/parser/ecmascript5/SkippedTokens/parserSkippedTokens20.ts:1:13] - 1 │ var v: X