From 7768d233c62c912c64c100af96ceaf4b3bd355d6 Mon Sep 17 00:00:00 2001 From: Egor Blinov Date: Wed, 3 Jul 2024 03:46:59 +0200 Subject: [PATCH] feat(isolated-declarations): support optional class methods (#4035) Example class ``` export class A { m1?(): void; m2(): void {} } ``` Before the fix: ``` export declare class A { m1(): void; } ``` with the fix: ``` export declare class A { m1?(): void; m2(): void; } ``` --- crates/oxc_codegen/src/gen.rs | 3 +++ crates/oxc_codegen/tests/mod.rs | 1 + crates/oxc_isolated_declarations/src/class.rs | 4 +++- crates/oxc_isolated_declarations/tests/fixtures/class.ts | 1 + crates/oxc_isolated_declarations/tests/snapshots/class.snap | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/oxc_codegen/src/gen.rs b/crates/oxc_codegen/src/gen.rs index 0dcc8a590a44..4f11d22fce27 100644 --- a/crates/oxc_codegen/src/gen.rs +++ b/crates/oxc_codegen/src/gen.rs @@ -2413,6 +2413,9 @@ impl<'a, const MINIFY: bool> Gen for MethodDefinition<'a> { if self.computed { p.print(b']'); } + if self.optional { + p.print(b'?'); + } if let Some(type_parameters) = self.value.type_parameters.as_ref() { type_parameters.gen(p, ctx); } diff --git a/crates/oxc_codegen/tests/mod.rs b/crates/oxc_codegen/tests/mod.rs index f834ac8e8d22..0189aca93405 100644 --- a/crates/oxc_codegen/tests/mod.rs +++ b/crates/oxc_codegen/tests/mod.rs @@ -201,6 +201,7 @@ fn typescript() { ); test_ts("let foo: { (t: T): void }", "let foo: {(t: T): void};\n", false); test_ts("function (){}", "function() {}\n", false); + test_ts("class A {m?(): void}", "class A {\n\tm?(): void;\n}\n", false); } fn test_comment_helper(source_text: &str, expected: &str) { diff --git a/crates/oxc_isolated_declarations/src/class.rs b/crates/oxc_isolated_declarations/src/class.rs index cadaa08d57cc..474d8c955604 100644 --- a/crates/oxc_isolated_declarations/src/class.rs +++ b/crates/oxc_isolated_declarations/src/class.rs @@ -336,7 +336,9 @@ impl<'a> IsolatedDeclarations<'a> { match element { ClassElement::StaticBlock(_) => {} ClassElement::MethodDefinition(ref method) => { - if !method.r#type.is_abstract() && method.value.body.is_none() { + if !(method.r#type.is_abstract() || method.optional) + && method.value.body.is_none() + { is_function_overloads = true; } else if is_function_overloads { // Skip implementation of function overloads diff --git a/crates/oxc_isolated_declarations/tests/fixtures/class.ts b/crates/oxc_isolated_declarations/tests/fixtures/class.ts index ae8b2713f155..209c7025f867 100644 --- a/crates/oxc_isolated_declarations/tests/fixtures/class.ts +++ b/crates/oxc_isolated_declarations/tests/fixtures/class.ts @@ -14,6 +14,7 @@ export class Zoo { export abstract class Qux { abstract foo(): void; + protected foo2?(): void; bar(): void {} baz(): void {} } diff --git a/crates/oxc_isolated_declarations/tests/snapshots/class.snap b/crates/oxc_isolated_declarations/tests/snapshots/class.snap index 5a598fed7d50..ab5cde1af936 100644 --- a/crates/oxc_isolated_declarations/tests/snapshots/class.snap +++ b/crates/oxc_isolated_declarations/tests/snapshots/class.snap @@ -15,6 +15,7 @@ export declare class Zoo { } export declare abstract class Qux { abstract foo(): void; + protected foo2?(): void; bar(): void; baz(): void; }