From c77db8e326e79c9768adf9c2cca93e09f4b360fd Mon Sep 17 00:00:00 2001 From: MichaelMitchell-at <=> Date: Sun, 7 Jul 2024 01:12:21 -0400 Subject: [PATCH] fix(isolated_declarations): Remove nested AssignmentPatterns from inside parameters --- .../src/formal_parameter_binding_pattern.rs | 24 +++++++++ .../oxc_isolated_declarations/src/function.rs | 3 ++ crates/oxc_isolated_declarations/src/lib.rs | 1 + .../tests/fixtures/function-parameters.ts | 4 ++ .../tests/snapshots/function-parameters.snap | 49 ++++++++++--------- 5 files changed, 57 insertions(+), 24 deletions(-) create mode 100644 crates/oxc_isolated_declarations/src/formal_parameter_binding_pattern.rs diff --git a/crates/oxc_isolated_declarations/src/formal_parameter_binding_pattern.rs b/crates/oxc_isolated_declarations/src/formal_parameter_binding_pattern.rs new file mode 100644 index 0000000000000..fb1372175af57 --- /dev/null +++ b/crates/oxc_isolated_declarations/src/formal_parameter_binding_pattern.rs @@ -0,0 +1,24 @@ +use oxc_ast::{ + ast::BindingPatternKind, visit::walk_mut::walk_binding_pattern_kind, AstBuilder, VisitMut, +}; + +pub struct FormalParameterBindingPattern<'a> { + ast: AstBuilder<'a>, +} + +impl<'a> VisitMut<'a> for FormalParameterBindingPattern<'a> { + fn visit_binding_pattern_kind(&mut self, kind: &mut BindingPatternKind<'a>) { + if let BindingPatternKind::AssignmentPattern(assignment) = kind { + *kind = self.ast.copy(&assignment.left.kind); + } + + walk_binding_pattern_kind(self, kind); + } +} + +impl<'a> FormalParameterBindingPattern<'a> { + pub fn remove_assignments_from_kind(ast: AstBuilder<'a>, kind: &mut BindingPatternKind<'a>) { + let mut visitor = FormalParameterBindingPattern { ast }; + visitor.visit_binding_pattern_kind(kind); + } +} diff --git a/crates/oxc_isolated_declarations/src/function.rs b/crates/oxc_isolated_declarations/src/function.rs index e2fe1489ebb03..06b99f6fc50d2 100644 --- a/crates/oxc_isolated_declarations/src/function.rs +++ b/crates/oxc_isolated_declarations/src/function.rs @@ -9,6 +9,7 @@ use crate::{ function_must_have_explicit_return_type, implicitly_adding_undefined_to_type, parameter_must_have_explicit_type, }, + formal_parameter_binding_pattern::FormalParameterBindingPattern, IsolatedDeclarations, }; @@ -65,6 +66,8 @@ impl<'a> IsolatedDeclarations<'a> { self.ast.copy(¶m.pattern) }; + FormalParameterBindingPattern::remove_assignments_from_kind(self.ast, &mut pattern.kind); + if is_assignment_pattern || pattern.type_annotation.is_none() { let type_annotation = pattern .type_annotation diff --git a/crates/oxc_isolated_declarations/src/lib.rs b/crates/oxc_isolated_declarations/src/lib.rs index 9a7584109dd31..8547028c550fd 100644 --- a/crates/oxc_isolated_declarations/src/lib.rs +++ b/crates/oxc_isolated_declarations/src/lib.rs @@ -9,6 +9,7 @@ mod class; mod declaration; mod diagnostics; mod r#enum; +mod formal_parameter_binding_pattern; mod function; mod inferrer; mod literal; diff --git a/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts b/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts index b43e3dfcb3881..6dd3b10ddadcc 100644 --- a/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts +++ b/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts @@ -10,6 +10,10 @@ export const fooGood2 = ({a, b}: object = { a: 1, b: 2 }): number => { return 2; } +const x = 42; +const y = ''; +export function fooGood3({a = x, b: [{c = y}]}: object): void {} + // Incorrect export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } export function fnDeclBad2(p: T = [], r2: T): void { } diff --git a/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap b/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap index 32ff3a31cade8..c006d77d4c613 100644 --- a/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap +++ b/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap @@ -8,6 +8,7 @@ export declare function fnDeclGood(p?: T, rParam?: string): void; export declare function fnDeclGood2(p?: T, rParam?: number): void; export declare function fooGood([a, b]?: any[]): number; export declare const fooGood2: ({ a, b }?: object) => number; +export declare function fooGood3({ a, b: [{ c }] }: object): void; export declare function fnDeclBad(p: T, rParam: T, r2: T): void; export declare function fnDeclBad2(p: T, r2: T): void; export declare function fnDeclBad3(p: T, rParam?: T, r2: T): void; @@ -19,54 +20,54 @@ export declare const fooBad2: () => number; x TS9025: Declaration emit for this parameter requires implicitly adding | undefined to it's type. This is not supported with --isolatedDeclarations. - ,-[14:30] - 13 | // Incorrect - 14 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + ,-[18:30] + 17 | // Incorrect + 18 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } : ^^^^^^^^^ - 15 | export function fnDeclBad2(p: T = [], r2: T): void { } + 19 | export function fnDeclBad2(p: T = [], r2: T): void { } `---- x TS9025: Declaration emit for this parameter requires implicitly adding | undefined to it's type. This is not supported with --isolatedDeclarations. - ,-[14:41] - 13 | // Incorrect - 14 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + ,-[18:41] + 17 | // Incorrect + 18 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } : ^^^^^^^^^^^^^^ - 15 | export function fnDeclBad2(p: T = [], r2: T): void { } + 19 | export function fnDeclBad2(p: T = [], r2: T): void { } `---- x TS9025: Declaration emit for this parameter requires implicitly adding | undefined to it's type. This is not supported with --isolatedDeclarations. - ,-[15:31] - 14 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } - 15 | export function fnDeclBad2(p: T = [], r2: T): void { } + ,-[19:31] + 18 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + 19 | export function fnDeclBad2(p: T = [], r2: T): void { } : ^^^^^^^^^ - 16 | export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } + 20 | export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } `---- x TS9025: Declaration emit for this parameter requires implicitly adding | undefined to it's type. This is not supported with --isolatedDeclarations. - ,-[16:31] - 15 | export function fnDeclBad2(p: T = [], r2: T): void { } - 16 | export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } + ,-[20:31] + 19 | export function fnDeclBad2(p: T = [], r2: T): void { } + 20 | export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } : ^^^^^^^^^ - 17 | + 21 | `---- x TS9011: Parameter must have an explicit type annotation with | --isolatedDeclarations. - ,-[18:24] - 17 | - 18 | export function fooBad([a, b] = [1, 2]): number { + ,-[22:24] + 21 | + 22 | export function fooBad([a, b] = [1, 2]): number { : ^^^^^^^^^^^^^^^ - 19 | return 2; + 23 | return 2; `---- x TS9011: Parameter must have an explicit type annotation with | --isolatedDeclarations. - ,-[22:25] - 21 | - 22 | export const fooBad2 = ({a, b} = { a: 1, b: 2 }): number => { + ,-[26:25] + 25 | + 26 | export const fooBad2 = ({a, b} = { a: 1, b: 2 }): number => { : ^^^^^^^^^^^^^^^^^^^^^^^ - 23 | return 2; + 27 | return 2; `----