From 9ea30c41ffd9ebae1f13825304cd43a96d6481af Mon Sep 17 00:00:00 2001 From: Dunqing <29533304+Dunqing@users.noreply.github.com> Date: Wed, 19 Jun 2024 14:05:58 +0000 Subject: [PATCH] feat(isolated-declarations): treat AssignmentPattern as optional (#3748) --- .../oxc_isolated_declarations/src/function.rs | 15 +++--- .../tests/fixtures/complex.ts | 1 - .../tests/fixtures/function-parameters.ts | 8 +++ .../tests/fixtures/simple.ts | 1 - crates/oxc_isolated_declarations/tests/mod.rs | 25 +++++++++- .../tests/snapshots/complex.snap | 5 -- .../tests/snapshots/function-parameters.snap | 49 +++++++++++++++++++ .../tests/snapshots/simple.snap | 5 -- 8 files changed, 88 insertions(+), 21 deletions(-) delete mode 100644 crates/oxc_isolated_declarations/tests/fixtures/complex.ts create mode 100644 crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts delete mode 100644 crates/oxc_isolated_declarations/tests/fixtures/simple.ts delete mode 100644 crates/oxc_isolated_declarations/tests/snapshots/complex.snap create mode 100644 crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap delete mode 100644 crates/oxc_isolated_declarations/tests/snapshots/simple.snap diff --git a/crates/oxc_isolated_declarations/src/function.rs b/crates/oxc_isolated_declarations/src/function.rs index 42b0708fc3c80..b92b9e0b1fb3c 100644 --- a/crates/oxc_isolated_declarations/src/function.rs +++ b/crates/oxc_isolated_declarations/src/function.rs @@ -41,7 +41,7 @@ impl<'a> IsolatedDeclarations<'a> { pub fn transform_formal_parameter( &self, param: &FormalParameter<'a>, - next_param: Option<&FormalParameter<'a>>, + is_remaining_params_have_required: bool, ) -> FormalParameter<'a> { let is_assignment_pattern = param.pattern.kind.is_assignment_pattern(); let mut pattern = @@ -52,9 +52,6 @@ impl<'a> IsolatedDeclarations<'a> { }; if is_assignment_pattern || pattern.type_annotation.is_none() { - let is_next_param_optional = - next_param.map_or(true, |next_param| next_param.pattern.optional); - let type_annotation = pattern .type_annotation .as_ref() @@ -70,7 +67,7 @@ impl<'a> IsolatedDeclarations<'a> { .map(|ts_type| { // jf next param is not optional and current param is assignment pattern // we need to add undefined to it's type - if !is_next_param_optional { + if is_remaining_params_have_required { if matches!(ts_type, TSType::TSTypeReference(_)) { self.error(implicitly_adding_undefined_to_type(param.span)); } else if !ts_type.is_maybe_undefined() { @@ -95,7 +92,7 @@ impl<'a> IsolatedDeclarations<'a> { self.ast.copy(&pattern.kind), type_annotation, // if it's assignment pattern, it's optional - pattern.optional || (is_next_param_optional && is_assignment_pattern), + pattern.optional || (!is_remaining_params_have_required && is_assignment_pattern), ); } @@ -119,7 +116,11 @@ impl<'a> IsolatedDeclarations<'a> { let items = self.ast.new_vec_from_iter(params.items.iter().enumerate().map(|(index, item)| { - self.transform_formal_parameter(item, params.items.get(index + 1)) + let is_remaining_params_have_required = + params.items.iter().skip(index).any(|item| { + !(item.pattern.optional || item.pattern.kind.is_assignment_pattern()) + }); + self.transform_formal_parameter(item, is_remaining_params_have_required) })); if let Some(rest) = ¶ms.rest { diff --git a/crates/oxc_isolated_declarations/tests/fixtures/complex.ts b/crates/oxc_isolated_declarations/tests/fixtures/complex.ts deleted file mode 100644 index 3a43d09b4ecc9..0000000000000 --- a/crates/oxc_isolated_declarations/tests/fixtures/complex.ts +++ /dev/null @@ -1 +0,0 @@ -class B {} diff --git a/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts b/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts new file mode 100644 index 0000000000000..7c68b8aebc0d7 --- /dev/null +++ b/crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts @@ -0,0 +1,8 @@ +// Correct +export function fnDeclGood(p: T = [], rParam = ""): void { }; +export function fnDeclGood2(p: T = [], rParam?: number): void { }; + +// Incorrect +export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } +export function fnDeclBad2(p: T = [], r2: T): void { } +export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } diff --git a/crates/oxc_isolated_declarations/tests/fixtures/simple.ts b/crates/oxc_isolated_declarations/tests/fixtures/simple.ts deleted file mode 100644 index a869c28495266..0000000000000 --- a/crates/oxc_isolated_declarations/tests/fixtures/simple.ts +++ /dev/null @@ -1 +0,0 @@ -class A {} diff --git a/crates/oxc_isolated_declarations/tests/mod.rs b/crates/oxc_isolated_declarations/tests/mod.rs index 1bfe840629b19..bf039e8120f5c 100644 --- a/crates/oxc_isolated_declarations/tests/mod.rs +++ b/crates/oxc_isolated_declarations/tests/mod.rs @@ -1,7 +1,8 @@ -use std::{fs, path::Path}; +use std::{fs, path::Path, sync::Arc}; use oxc_allocator::Allocator; use oxc_codegen::CodeGenerator; +use oxc_isolated_declarations::IsolatedDeclarations; use oxc_parser::Parser; use oxc_span::SourceType; @@ -9,7 +10,27 @@ fn transform(path: &Path, source_text: &str) -> String { let allocator = Allocator::default(); let source_type = SourceType::from_path(path).unwrap(); let program = Parser::new(&allocator, source_text, source_type).parse().program; - CodeGenerator::new().build(&program).source_text + + let ret = IsolatedDeclarations::new(&allocator).build(&program); + let code = CodeGenerator::new().build(&ret.program).source_text; + + let mut snapshot = format!("==================== .D.TS ====================\n\n{code}\n\n"); + if !ret.errors.is_empty() { + let source = Arc::new(source_text.to_string()); + let error_messages = ret + .errors + .iter() + .map(|d| d.clone().with_source_code(Arc::clone(&source))) + .map(|error| format!("{error:?}")) + .collect::>() + .join("\n"); + + snapshot.push_str(&format!( + "==================== Errors ====================\n\n{error_messages}\n\n" + )); + } + + snapshot } #[test] diff --git a/crates/oxc_isolated_declarations/tests/snapshots/complex.snap b/crates/oxc_isolated_declarations/tests/snapshots/complex.snap deleted file mode 100644 index eabe97507a9cc..0000000000000 --- a/crates/oxc_isolated_declarations/tests/snapshots/complex.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: crates/oxc_isolated_declarations/tests/mod.rs -input_file: crates/oxc_isolated_declarations/tests/fixtures/complex.ts ---- -class B {} diff --git a/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap b/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap new file mode 100644 index 0000000000000..8049fdd996d31 --- /dev/null +++ b/crates/oxc_isolated_declarations/tests/snapshots/function-parameters.snap @@ -0,0 +1,49 @@ +--- +source: crates/oxc_isolated_declarations/tests/mod.rs +input_file: crates/oxc_isolated_declarations/tests/fixtures/function-parameters.ts +--- +==================== .D.TS ==================== + +export declare function fnDeclGood(p?: T, rParam?: string): void; +export declare function fnDeclGood2(p?: T, rParam?: number): 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; + + +==================== Errors ==================== + + x Declaration emit for this parameter requires implicitly adding undefined + | to it's type. This is not supported with --isolatedDeclarations. + ,-[6:30] + 5 | // Incorrect + 6 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + : ^^^^^^^^^ + 7 | export function fnDeclBad2(p: T = [], r2: T): void { } + `---- + + x Declaration emit for this parameter requires implicitly adding undefined + | to it's type. This is not supported with --isolatedDeclarations. + ,-[6:41] + 5 | // Incorrect + 6 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + : ^^^^^^^^^^^^^^ + 7 | export function fnDeclBad2(p: T = [], r2: T): void { } + `---- + + x Declaration emit for this parameter requires implicitly adding undefined + | to it's type. This is not supported with --isolatedDeclarations. + ,-[7:31] + 6 | export function fnDeclBad(p: T = [], rParam: T = "", r2: T): void { } + 7 | export function fnDeclBad2(p: T = [], r2: T): void { } + : ^^^^^^^^^ + 8 | export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } + `---- + + x Declaration emit for this parameter requires implicitly adding undefined + | to it's type. This is not supported with --isolatedDeclarations. + ,-[8:31] + 7 | export function fnDeclBad2(p: T = [], r2: T): void { } + 8 | export function fnDeclBad3(p: T = [], rParam?: T, r2: T): void { } + : ^^^^^^^^^ + `---- diff --git a/crates/oxc_isolated_declarations/tests/snapshots/simple.snap b/crates/oxc_isolated_declarations/tests/snapshots/simple.snap deleted file mode 100644 index 82dd57f85bfb2..0000000000000 --- a/crates/oxc_isolated_declarations/tests/snapshots/simple.snap +++ /dev/null @@ -1,5 +0,0 @@ ---- -source: crates/oxc_isolated_declarations/tests/mod.rs -input_file: crates/oxc_isolated_declarations/tests/fixtures/simple.ts ---- -class A {}