diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index 7c750536bf2c0..d0e5ac1411618 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -100,6 +100,13 @@ pub fn merge_conflict_marker( diagnostic } +#[cold] +pub fn jsx_in_non_jsx(span: Span) -> OxcDiagnostic { + OxcDiagnostic::error("Unexpected JSX expression") + .with_label(span) + .with_help("JSX syntax is disabled and should be enabled via the parser options") +} + #[cold] pub fn expect_token(x0: &str, x1: &str, span: Span) -> OxcDiagnostic { OxcDiagnostic::error(format!("Expected `{x0}` but found `{x1}`")) diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index b903d2d60f7f1..9d7402e0083ad 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -1082,7 +1082,16 @@ impl<'a> ParserImpl<'a> { if self.is_ts { return self.parse_ts_type_assertion(); } - self.unexpected() + + let checkpoint = self.checkpoint_with_error_recovery(); + let start = self.start_span(); + self.parse_jsx_expression(); + if self.fatal_error.is_none() { + self.fatal_error(diagnostics::jsx_in_non_jsx(self.end_span(start))) + } else { + self.rewind(checkpoint); + self.unexpected() + } } Kind::Await if self.is_await_expression() => self.parse_await_expression(lhs_span), _ => self.parse_update_expression(lhs_span), diff --git a/tasks/coverage/misc/fail/jsx-in-js.js b/tasks/coverage/misc/fail/jsx-in-js.js new file mode 100644 index 0000000000000..b73190dc1b9a3 --- /dev/null +++ b/tasks/coverage/misc/fail/jsx-in-js.js @@ -0,0 +1 @@ +export const foo = ; diff --git a/tasks/coverage/misc/fail/jsx-like-in-js.js b/tasks/coverage/misc/fail/jsx-like-in-js.js new file mode 100644 index 0000000000000..02748e3d67940 --- /dev/null +++ b/tasks/coverage/misc/fail/jsx-like-in-js.js @@ -0,0 +1 @@ +export const foo = Hello - · ─ + · ────────── 4 │ ); ╰──── + help: JSX syntax is disabled and should be enabled via the parser options - × Unexpected token + × Unexpected JSX expression ╭─[babel/packages/babel-parser/test/fixtures/jsx/errors/_no-plugin-jsx-expression/input.js:1:1] 1 │
{name}
- · ─ + · ───────────────── ╰──── + help: JSX syntax is disabled and should be enabled via the parser options × Unexpected token ╭─[babel/packages/babel-parser/test/fixtures/jsx/errors/_no-plugin-type-param/input.js:1:1] @@ -12627,18 +12629,22 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ─ ╰──── - × Unexpected token + × Unexpected JSX expression ╭─[babel/packages/babel-parser/test/fixtures/jsx/errors/_no_plugin/input.js:1:1] 1 │
- · ─ + · ─────────── ╰──── + help: JSX syntax is disabled and should be enabled via the parser options - × Unexpected token + × Unexpected JSX expression ╭─[babel/packages/babel-parser/test/fixtures/jsx/errors/_no_plugin-non-BMP-identifier/input.js:1:1] - 1 │ < - · ─ - 2 │ 𠮷 + 1 │ ╭─▶ < + 2 │ │ 𠮷 + 3 │ │ > ╰──── + help: JSX syntax is disabled and should be enabled via the parser options × Unexpected token. Did you mean `{'>'}` or `>`? ╭─[babel/packages/babel-parser/test/fixtures/jsx/errors/unclosed-jsx-element/input.js:1:10] diff --git a/tasks/coverage/snapshots/parser_misc.snap b/tasks/coverage/snapshots/parser_misc.snap index 3892e95c909bd..dd5317767a255 100644 --- a/tasks/coverage/snapshots/parser_misc.snap +++ b/tasks/coverage/snapshots/parser_misc.snap @@ -1,7 +1,7 @@ parser_misc Summary: AST Parsed : 49/49 (100.00%) Positive Passed: 49/49 (100.00%) -Negative Passed: 108/108 (100.00%) +Negative Passed: 110/110 (100.00%) × Cannot assign to 'arguments' in strict mode ╭─[misc/fail/arguments-eval.ts:1:10] @@ -180,6 +180,19 @@ Negative Passed: 108/108 (100.00%) · ╰── `,` or `]` expected ╰──── + × Unexpected JSX expression + ╭─[misc/fail/jsx-in-js.js:1:20] + 1 │ export const foo = ; + · ─────── + ╰──── + help: JSX syntax is disabled and should be enabled via the parser options + + × Unexpected token + ╭─[misc/fail/jsx-like-in-js.js:1:20] + 1 │ export const foo = < - · ─ + · ───── ╰──── + help: JSX syntax is disabled and should be enabled via the parser options × Unexpected token ╭─[typescript/tests/cases/compiler/parseJsxElementInUnaryExpressionNoCrash3.ts:1:2]