Skip to content

Commit

Permalink
fix(parser): parse empty method declaration as TSEmptyBodyFunctionExp…
Browse files Browse the repository at this point in the history
…ression (#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](https://astexplorer.net/#/gist/9f43cf0fe91760e11f1572934681c92f/d38530204eaa6e12dbd14f3ef2d7d2fcb7da7bc2)
as `FunctionExpression` with an empty body
- By
[TS-ESLint](https://astexplorer.net/#/gist/626dd346956a02c221d4e128450652af/4ea4e2feb5ae7bb8787f8c7e452d442c935c1f09)
as
[TSEmptyBodyFunctionExpression](typescript-eslint/typescript-eslint#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](babel/babel#13878) about that.

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

---------

Co-authored-by: Boshen <[email protected]>
  • Loading branch information
ArnaudBarre and Boshen authored Mar 3, 2024
1 parent 9479865 commit d9cc429
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 17 deletions.
2 changes: 2 additions & 0 deletions crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
20 changes: 13 additions & 7 deletions crates/oxc_parser/src/js/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
18 changes: 8 additions & 10 deletions tasks/coverage/parser_typescript.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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 }
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit d9cc429

Please sign in to comment.