From 1d04c0a9e286cf1e508958f7b71350d6c3aa83fd Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Fri, 12 Apr 2024 11:01:23 +0200 Subject: [PATCH] fix(fast_check): correctly handle rest parameters Previously rest parameters had an optional type annotation added to them when generated for overload positions. This is wrong. Additionally rest parameters in overloaded constructors were not handled correctly at all. --- src/fast_check/transform.rs | 44 ++++++++++++++----- tests/specs/graph/jsr/FastCheck_Overloads.txt | 41 ++++++++++------- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/src/fast_check/transform.rs b/src/fast_check/transform.rs index 89afdc124..de2713624 100644 --- a/src/fast_check/transform.rs +++ b/src/fast_check/transform.rs @@ -734,18 +734,38 @@ impl<'a> FastCheckTransformer<'a> { let is_overload = self.public_ranges.is_impl_with_overloads(&n.range()); if is_overload { for (i, param) in n.params.iter_mut().enumerate() { - *param = ParamOrTsParamProp::Param(Param { - span: DUMMY_SP, - decorators: Vec::new(), - pat: Pat::Ident(BindingIdent { - id: Ident { + if param.as_param().map(|p| p.pat.is_rest()).unwrap_or(false) { + *param = ParamOrTsParamProp::Param(Param { + span: DUMMY_SP, + decorators: Vec::new(), + pat: Pat::Rest(RestPat { span: DUMMY_SP, - sym: format!("param{}", i).into(), - optional: true, - }, - type_ann: Some(any_type_ann()), - }), - }); + dot3_token: DUMMY_SP, + type_ann: Some(any_type_ann()), + arg: Box::new(Pat::Ident(BindingIdent { + id: Ident { + span: DUMMY_SP, + sym: format!("param{}", i).into(), + optional: false, + }, + type_ann: None, + })), + }), + }); + } else { + *param = ParamOrTsParamProp::Param(Param { + span: DUMMY_SP, + decorators: Vec::new(), + pat: Pat::Ident(BindingIdent { + id: Ident { + span: DUMMY_SP, + sym: format!("param{}", i).into(), + optional: true, + }, + type_ann: Some(any_type_ann()), + }), + }); + } } } @@ -925,7 +945,7 @@ impl<'a> FastCheckTransformer<'a> { id: Ident { span: DUMMY_SP, sym: format!("param{}", i).into(), - optional: true, + optional: false, }, type_ann: None, })), diff --git a/tests/specs/graph/jsr/FastCheck_Overloads.txt b/tests/specs/graph/jsr/FastCheck_Overloads.txt index b34053113..9c3a3ca6d 100644 --- a/tests/specs/graph/jsr/FastCheck_Overloads.txt +++ b/tests/specs/graph/jsr/FastCheck_Overloads.txt @@ -6,19 +6,23 @@ # https://jsr.io/@scope/a/1.0.0/mod.ts export class argsToArray { + constructor(..._args: string[]); + constructor(..._args: number[]); + constructor(..._args: unknown[]) {} + argsToArray(..._args: string[]): void; argsToArray(..._args: number[]): void; argsToArray(..._args: unknown[]): void {} } -export function overloadSpread(...args: string[]); -export function overloadSpread(...args: number[]); +export function overloadSpread(...args: string[]): void; +export function overloadSpread(...args: number[]): void; export function overloadSpread(...args: unknown[]) { return args; } -export function overloadLast(value: string, ...args: string[]); -export function overloadLast(value: number, ...args: number[]); +export function overloadLast(value: string, ...args: string[]): void; +export function overloadLast(value: number, ...args: number[]): void; export function overloadLast(value: string | number, ...args: unknown[]) { return args; } @@ -58,7 +62,7 @@ import 'jsr:@scope/a' }, { "kind": "esm", - "size": 549, + "size": 682, "mediaType": "TypeScript", "specifier": "https://jsr.io/@scope/a/1.0.0/mod.ts" } @@ -74,28 +78,33 @@ import 'jsr:@scope/a' Fast check https://jsr.io/@scope/a/1.0.0/mod.ts: {} export class argsToArray { + constructor(..._args: string[]); + constructor(..._args: number[]); + constructor(...param0: any){} argsToArray(..._args: string[]): void; argsToArray(..._args: number[]): void; - argsToArray(...param0?: any): any { + argsToArray(...param0: any): any { return {} as never; } } - export function overloadSpread(...args: string[]); - export function overloadSpread(...args: number[]); - export function overloadSpread(...param0?: any): any { + export function overloadSpread(...args: string[]): void; + export function overloadSpread(...args: number[]): void; + export function overloadSpread(...param0: any): any { return {} as never; } - export function overloadLast(value: string, ...args: string[]); - export function overloadLast(value: number, ...args: number[]); - export function overloadLast(param0?: any, ...param1?: any): any { + export function overloadLast(value: string, ...args: string[]): void; + export function overloadLast(value: number, ...args: number[]): void; + export function overloadLast(param0?: any, ...param1: any): any { return {} as never; } --- DTS --- export declare class argsToArray { + constructor(..._args: string[]); + constructor(..._args: number[]); argsToArray(..._args: string[]): void; argsToArray(..._args: number[]): void; } - export declare function overloadSpread(...args: string[]); - export declare function overloadSpread(...args: number[]); - export declare function overloadLast(value: string, ...args: string[]); - export declare function overloadLast(value: number, ...args: number[]); + export declare function overloadSpread(...args: string[]): void; + export declare function overloadSpread(...args: number[]): void; + export declare function overloadLast(value: string, ...args: string[]): void; + export declare function overloadLast(value: number, ...args: number[]): void;