fix(parser): parse empty method declaration as TSEmptyBodyFunctionExpression (#2574)

That a tricky one, because it's time to decide what does ESTree
compliant means in the TS world (re #2463)

This code:

```ts
export declare class ByteBuffer {
  clear(): void;
     // ^^
}
```

- Is parsed by
[Babel](d38530204e)
as `FunctionExpression` with an empty body
- By
[TS-ESLint](4ea4e2feb5)
as
[TSEmptyBodyFunctionExpression](https://github.com/typescript-eslint/typescript-eslint/pull/1289)
- By
[OXC](https://oxc-project.github.io/oxc/playground/?code=3YCAAIC1gICAgICAgICyHorESipoTXPdvBaE9wxzlOraoWs19SUxDvdcwSVU0kbBO2b7ppX3x2P5IhQlpGHOYEHNCEfLf38HUICA)
as `TSDeclareFunction`

I'm going the easy way to fix this to the Babel way, but I think
following TS-ESLint would make sense. There is an [open babel
issue](https://github.com/babel/babel/issues/13878) about that.

Edit: Ok that not so easy and require updating some logic.

---------

Co-authored-by: Boshen <boshenc@gmail.com>
This commit is contained in:
Arnaud Barré 2024-03-03 14:59:17 +01:00 committed by GitHub
parent 9479865d9b
commit d9cc429d4a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 23 additions and 17 deletions

View file

@ -1770,6 +1770,8 @@ pub enum FunctionType {
FunctionDeclaration,
FunctionExpression,
TSDeclareFunction,
/// <https://github.com/typescript-eslint/typescript-eslint/pull/1289>
TSEmptyBodyFunctionExpression,
}
/// <https://tc39.es/ecma262/#prod-FormalParameters>

View file

@ -105,16 +105,22 @@ impl<'a> ParserImpl<'a> {
return Err(self.unexpected());
}
let function_type = if body.is_none() {
FunctionType::TSDeclareFunction
} else {
match func_kind {
FunctionKind::Declaration { .. } | FunctionKind::DefaultExport => {
let function_type = match func_kind {
FunctionKind::Declaration { .. } | FunctionKind::DefaultExport => {
if body.is_none() {
FunctionType::TSDeclareFunction
} else {
FunctionType::FunctionDeclaration
}
FunctionKind::Expression { .. } => FunctionType::FunctionExpression,
FunctionKind::TSDeclaration { .. } => FunctionType::TSDeclareFunction,
}
FunctionKind::Expression { .. } => {
if body.is_none() {
FunctionType::TSEmptyBodyFunctionExpression
} else {
FunctionType::FunctionExpression
}
}
FunctionKind::TSDeclaration { .. } => FunctionType::TSDeclareFunction,
};
if FunctionType::TSDeclareFunction == function_type {

View file

@ -1326,7 +1326,6 @@ Expect Syntax Error: "compiler/objectLiteralFreshnessWithSpread.ts"
Expect Syntax Error: "compiler/objectLiteralFunctionArgContextualTyping.ts"
Expect Syntax Error: "compiler/objectLiteralFunctionArgContextualTyping2.ts"
Expect Syntax Error: "compiler/objectLiteralIndexerErrors.ts"
Expect Syntax Error: "compiler/objectLiteralMemberWithoutBlock1.ts"
Expect Syntax Error: "compiler/objectLiteralParameterResolution.ts"
Expect Syntax Error: "compiler/objectLiteralPropertyImplicitlyAny.ts"
Expect Syntax Error: "compiler/objectLiteralReferencingInternalProperties.ts"
@ -3550,6 +3549,7 @@ Expect Syntax Error: "conformance/types/nonPrimitive/nonPrimitiveUnionIntersecti
Expect Syntax Error: "conformance/types/objectTypeLiteral/callSignatures/callSignatureWithOptionalParameterAndInitializer.ts"
Expect Syntax Error: "conformance/types/objectTypeLiteral/callSignatures/callSignaturesThatDifferOnlyByReturnType2.ts"
Expect Syntax Error: "conformance/types/objectTypeLiteral/callSignatures/callSignaturesWithParameterInitializers.ts"
Expect Syntax Error: "conformance/types/objectTypeLiteral/callSignatures/callSignaturesWithParameterInitializers2.ts"
Expect Syntax Error: "conformance/types/objectTypeLiteral/callSignatures/specializedSignatureIsNotSubtypeOfNonSpecializedSignature.ts"
Expect Syntax Error: "conformance/types/objectTypeLiteral/callSignatures/stringLiteralTypesInImplementationSignatures2.ts"
Expect Syntax Error: "conformance/types/objectTypeLiteral/callSignatures/typeParameterUsedAsTypeParameterConstraint4.ts"
@ -7941,6 +7941,13 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
· ╰── `,` expected
╰────
× Expected `,` but found `;`
╭─[compiler/objectLiteralMemberWithoutBlock1.ts:1:16]
1 │ var v = { foo(); }
· ┬
· ╰── `,` expected
╰────
× Expected `,` but found `;`
╭─[compiler/objectLiteralWithSemicolons1.ts:1:12]
1 │ var v = { a; b; c }
@ -19577,15 +19584,6 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
38 │ }
╰────
× Expected a semicolon or an implicit semicolon after a statement, but found none
╭─[conformance/types/objectTypeLiteral/callSignatures/callSignaturesWithParameterInitializers2.ts:20:15]
19 │ var b = {
20 │ foo(x = 1), // error
· ▲
21 │ foo(x = 1) { }, // error
╰────
help: Try insert a semicolon here
× A parameter property is only allowed in a constructor implementation.
╭─[conformance/types/objectTypeLiteral/callSignatures/constructSignatureWithAccessibilityModifiersOnParameters.ts:16:10]
15 │ interface I {