diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index d0e5ac1411618..21a9cae8cd5a6 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -1082,3 +1082,10 @@ pub fn invalid_rest_assignment_target(span: Span) -> OxcDiagnostic { pub fn modifiers_cannot_appear_here(span: Span) -> OxcDiagnostic { ts_error("1184", "Modifiers cannot appear here.").with_label(span) } + +#[cold] +pub fn expect_function_body(span: Span) -> OxcDiagnostic { + OxcDiagnostic::error("Expected function body") + .with_label(span) + .with_help("Add a function body (`{}`).") +} diff --git a/crates/oxc_parser/src/js/function.rs b/crates/oxc_parser/src/js/function.rs index 0b05efa8c343c..ccbe2d85e6563 100644 --- a/crates/oxc_parser/src/js/function.rs +++ b/crates/oxc_parser/src/js/function.rs @@ -134,7 +134,7 @@ impl<'a> ParserImpl<'a> { 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 self.unexpected(); + return self.fatal_error(diagnostics::expect_function_body(self.end_span(span))); } let function_type = match func_kind { FunctionKind::Declaration | FunctionKind::DefaultExport => { diff --git a/tasks/coverage/snapshots/parser_babel.snap b/tasks/coverage/snapshots/parser_babel.snap index fb137b8e49ffb..d4f704d42a8a3 100644 --- a/tasks/coverage/snapshots/parser_babel.snap +++ b/tasks/coverage/snapshots/parser_babel.snap @@ -4596,11 +4596,12 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ╰── `}` expected ╰──── - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/268/input.js:1:14] + × Expected function body + ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/268/input.js:1:1] 1 │ function a() 1 // expression closure is not supported - · ─ + · ──────────── ╰──── + help: Add a function body (`{}`). × Unexpected token ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/273/input.js:1:10] @@ -4634,10 +4635,12 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ───── ╰──── - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/278/input.js:1:24] + × Expected function body + ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/278/input.js:1:1] 1 │ function f(a, ...b = 0) + · ─────────────────────── ╰──── + help: Add a function body (`{}`). × Identifier `a` has already been declared ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/280/input.js:1:26] @@ -4815,23 +4818,26 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc · ─── ╰──── - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/340/input.js:1:16] + × Expected function body + ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/340/input.js:1:13] 1 │ x = { method() 42 } - · ── + · ── ╰──── + help: Add a function body (`{}`). - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/341/input.js:1:20] + × Expected function body + ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/341/input.js:1:17] 1 │ x = { get method() 42 } - · ── + · ── ╰──── + help: Add a function body (`{}`). - × Unexpected token - ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/342/input.js:1:23] + × Expected function body + ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/342/input.js:1:17] 1 │ x = { set method(val) v = val } - · ─ + · ───── ╰──── + help: Add a function body (`{}`). × 'super' can only be used with function calls or in property accesses ╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/344/input.js:1:1] diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index 3889bc233d929..a6f42f8612bef 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -7191,13 +7191,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va 16 │ b = 10; ╰──── - × Unexpected token - ╭─[typescript/tests/cases/compiler/jsFileCompilationConstructorOverloadSyntax.ts:2:16] + × Expected function body + ╭─[typescript/tests/cases/compiler/jsFileCompilationConstructorOverloadSyntax.ts:2:14] 1 │ class A { 2 │ constructor(); - · ─ + · ── 3 │ } ╰──── + help: Add a function body (`{}`). × Unexpected token ╭─[typescript/tests/cases/compiler/jsFileCompilationEnumSyntax.ts:1:1] @@ -7211,11 +7212,12 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va · ─ ╰──── - × Unexpected token - ╭─[typescript/tests/cases/compiler/jsFileCompilationFunctionOverloadSyntax.ts:1:15] + × Expected function body + ╭─[typescript/tests/cases/compiler/jsFileCompilationFunctionOverloadSyntax.ts:1:1] 1 │ function foo(); - · ─ + · ────────────── ╰──── + help: Add a function body (`{}`). × TS(8002): 'import ... =' can only be used in TypeScript files. ╭─[typescript/tests/cases/compiler/jsFileCompilationImportEqualsSyntax.ts:1:1] @@ -7231,13 +7233,14 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va ╰──── help: Try inserting a semicolon here - × Unexpected token - ╭─[typescript/tests/cases/compiler/jsFileCompilationMethodOverloadSyntax.ts:2:8] + × Expected function body + ╭─[typescript/tests/cases/compiler/jsFileCompilationMethodOverloadSyntax.ts:2:6] 1 │ class A { 2 │ foo(); - · ─ + · ── 3 │ } ╰──── + help: Add a function body (`{}`). × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[typescript/tests/cases/compiler/jsFileCompilationModuleSyntax.ts:1:10] @@ -7268,11 +7271,12 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va ╰──── help: No modifiers are allowed here. - × Unexpected token - ╭─[typescript/tests/cases/compiler/jsFileCompilationReturnTypeSyntaxOfFunction.ts:1:13] + × Expected function body + ╭─[typescript/tests/cases/compiler/jsFileCompilationReturnTypeSyntaxOfFunction.ts:1:1] 1 │ function F(): number { } - · ─ + · ──────────── ╰──── + help: Add a function body (`{}`). × Expected a semicolon or an implicit semicolon after a statement, but found none ╭─[typescript/tests/cases/compiler/jsFileCompilationTypeAliasSyntax.ts:1:5]