diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index 44beefcbd8517..0cd7616f02e51 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -435,16 +435,6 @@ pub fn jsx_expressions_may_not_use_the_comma_operator(span: Span) -> OxcDiagnost .with_label(span) } -#[cold] -pub fn line_terminator_before_using_declaration(span: Span) -> OxcDiagnostic { - OxcDiagnostic::error("Line terminator not permitted before using declaration.").with_label(span) -} - -#[cold] -pub fn await_in_using_declaration(span: Span) -> OxcDiagnostic { - OxcDiagnostic::error("Await is not allowed in using declarations.").with_label(span) -} - #[cold] pub fn invalid_identifier_in_using_declaration(span: Span) -> OxcDiagnostic { OxcDiagnostic::error("Using declarations may not have binding patterns.").with_label(span) diff --git a/crates/oxc_parser/src/js/declaration.rs b/crates/oxc_parser/src/js/declaration.rs index d2503886e4e51..5eb8cd6015bfc 100644 --- a/crates/oxc_parser/src/js/declaration.rs +++ b/crates/oxc_parser/src/js/declaration.rs @@ -143,19 +143,6 @@ impl<'a> ParserImpl<'a> { self.expect(Kind::Using)?; - // `[no LineTerminator here]` - if self.cur_token().is_on_new_line { - self.error(diagnostics::line_terminator_before_using_declaration( - self.cur_token().span(), - )); - } - - // [lookahead ≠ await] - if self.cur_kind() == Kind::Await { - self.error(diagnostics::await_in_using_declaration(self.cur_token().span())); - self.eat(Kind::Await); - } - // BindingList[?In, ?Yield, ?Await, ~Pattern] let mut declarations: oxc_allocator::Vec<'_, VariableDeclarator<'_>> = self.ast.vec(); loop { diff --git a/crates/oxc_parser/src/js/statement.rs b/crates/oxc_parser/src/js/statement.rs index e0261b9abceaa..5e53f12ec8678 100644 --- a/crates/oxc_parser/src/js/statement.rs +++ b/crates/oxc_parser/src/js/statement.rs @@ -114,20 +114,42 @@ impl<'a> ParserImpl<'a> { // Fast path Kind::Function => self.parse_function_declaration(stmt_ctx), Kind::Let if !self.cur_token().escaped() => self.parse_let(stmt_ctx), + // Peek tokens + Kind::Async + if { + let peek_token = self.peek_token(); + peek_token.kind == Kind::Function && !peek_token.is_on_new_line + } => + { + self.parse_function_declaration(stmt_ctx) + } Kind::Import if !matches!(self.peek_kind(), Kind::Dot | Kind::LParen) => { self.parse_import_declaration() } - Kind::Const if !(self.is_ts && self.is_at_enum_declaration()) => { + Kind::Const if !(self.is_ts && self.peek_at(Kind::Enum)) => { self.parse_variable_statement(stmt_ctx) } - Kind::Await - if self.peek_kind() == Kind::Using && self.nth_kind(2).is_binding_identifier() => + Kind::Using + if { + let peek_token = self.peek_token(); + peek_token.kind.is_binding_identifier() && !peek_token.is_on_new_line + } => { self.parse_using_statement() } - Kind::Using if self.peek_kind().is_binding_identifier() => self.parse_using_statement(), - Kind::Async if self.peek_at(Kind::Function) && !self.peek_token().is_on_new_line => { - self.parse_function_declaration(stmt_ctx) + // Peek 2 tokens + Kind::Await + if { + let peek_token = self.peek_token(); + if peek_token.kind == Kind::Using && !peek_token.is_on_new_line { + let peek2_token = self.nth(2); + peek2_token.kind.is_binding_identifier() && !peek2_token.is_on_new_line + } else { + false + } + } => + { + self.parse_using_statement() } _ if self.is_ts && self.at_start_of_ts_declaration() => { self.parse_ts_declaration_statement(start_span) diff --git a/crates/oxc_parser/src/ts/statement.rs b/crates/oxc_parser/src/ts/statement.rs index 5799fcf5c46f3..9466f8301bbb5 100644 --- a/crates/oxc_parser/src/ts/statement.rs +++ b/crates/oxc_parser/src/ts/statement.rs @@ -12,11 +12,6 @@ use crate::{ impl<'a> ParserImpl<'a> { /* ------------------- Enum ------------------ */ - - pub(crate) fn is_at_enum_declaration(&mut self) -> bool { - self.at(Kind::Enum) || (self.at(Kind::Const) && self.peek_at(Kind::Enum)) - } - /// `https://www.typescriptlang.org/docs/handbook/enums.html` pub(crate) fn parse_ts_enum_declaration( &mut self, diff --git a/tasks/coverage/misc/pass/oxc-10503.ts b/tasks/coverage/misc/pass/oxc-10503.ts new file mode 100644 index 0000000000000..8c0bbd2d6e7f6 --- /dev/null +++ b/tasks/coverage/misc/pass/oxc-10503.ts @@ -0,0 +1,5 @@ +using +foo = bar(); + +await using +foo = bar(); diff --git a/tasks/coverage/snapshots/codegen_misc.snap b/tasks/coverage/snapshots/codegen_misc.snap index 614cc1865e797..43f781ca30240 100644 --- a/tasks/coverage/snapshots/codegen_misc.snap +++ b/tasks/coverage/snapshots/codegen_misc.snap @@ -1,3 +1,3 @@ codegen_misc Summary: -AST Parsed : 34/34 (100.00%) -Positive Passed: 34/34 (100.00%) +AST Parsed : 35/35 (100.00%) +Positive Passed: 35/35 (100.00%) diff --git a/tasks/coverage/snapshots/parser_misc.snap b/tasks/coverage/snapshots/parser_misc.snap index ecf1285422606..f7fd7f139096e 100644 --- a/tasks/coverage/snapshots/parser_misc.snap +++ b/tasks/coverage/snapshots/parser_misc.snap @@ -1,6 +1,6 @@ parser_misc Summary: -AST Parsed : 34/34 (100.00%) -Positive Passed: 34/34 (100.00%) +AST Parsed : 35/35 (100.00%) +Positive Passed: 35/35 (100.00%) Negative Passed: 31/31 (100.00%) × Identifier `b` has already been declared diff --git a/tasks/coverage/snapshots/semantic_misc.snap b/tasks/coverage/snapshots/semantic_misc.snap index 806c49746f870..bc81df867f7e8 100644 --- a/tasks/coverage/snapshots/semantic_misc.snap +++ b/tasks/coverage/snapshots/semantic_misc.snap @@ -1,6 +1,6 @@ semantic_misc Summary: -AST Parsed : 34/34 (100.00%) -Positive Passed: 19/34 (55.88%) +AST Parsed : 35/35 (100.00%) +Positive Passed: 20/35 (57.14%) tasks/coverage/misc/pass/oxc-1288.ts semantic error: Bindings mismatch: after transform: ScopeId(0): ["from"] diff --git a/tasks/coverage/snapshots/transformer_misc.snap b/tasks/coverage/snapshots/transformer_misc.snap index b17f9c51ca5cc..c9b0be2ed71a2 100644 --- a/tasks/coverage/snapshots/transformer_misc.snap +++ b/tasks/coverage/snapshots/transformer_misc.snap @@ -1,3 +1,3 @@ transformer_misc Summary: -AST Parsed : 34/34 (100.00%) -Positive Passed: 34/34 (100.00%) +AST Parsed : 35/35 (100.00%) +Positive Passed: 35/35 (100.00%)