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 │ │ >
+ 4 │ │ 𠮷
+ 5 │ ╰─▶ >
╰────
+ 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]