From 523d1e2166ebb5b2b8ea98058a72056f37551d52 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Thu, 11 Apr 2024 21:56:01 +0200 Subject: [PATCH] fix(fast_check): properly handle rest parameters in overloads (#432) --- src/fast_check/transform.rs | 42 ++++++-- tests/specs/graph/jsr/FastCheck_Overloads.txt | 101 ++++++++++++++++++ 2 files changed, 132 insertions(+), 11 deletions(-) create mode 100644 tests/specs/graph/jsr/FastCheck_Overloads.txt diff --git a/src/fast_check/transform.rs b/src/fast_check/transform.rs index d2db747b8..dd009ad0b 100644 --- a/src/fast_check/transform.rs +++ b/src/fast_check/transform.rs @@ -911,18 +911,38 @@ impl<'a> FastCheckTransformer<'a> { } if is_overload { for (i, param) in n.params.iter_mut().enumerate() { - *param = Param { - span: DUMMY_SP, - decorators: Vec::new(), - pat: Pat::Ident(BindingIdent { - id: Ident { + if param.pat.is_rest() { + *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: true, + }, + type_ann: None, + })), + }), + }; + } else { + *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()), + }), + }; + } } n.return_type = Some(any_type_ann()); } diff --git a/tests/specs/graph/jsr/FastCheck_Overloads.txt b/tests/specs/graph/jsr/FastCheck_Overloads.txt new file mode 100644 index 000000000..b34053113 --- /dev/null +++ b/tests/specs/graph/jsr/FastCheck_Overloads.txt @@ -0,0 +1,101 @@ +# https://jsr.io/@scope/a/meta.json +{"versions": { "1.0.0": {} } } + +# https://jsr.io/@scope/a/1.0.0_meta.json +{ "exports": { ".": "./mod.ts" } } + +# https://jsr.io/@scope/a/1.0.0/mod.ts +export class argsToArray { + 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: unknown[]) { + return args; +} + +export function overloadLast(value: string, ...args: string[]); +export function overloadLast(value: number, ...args: number[]); +export function overloadLast(value: string | number, ...args: unknown[]) { + return args; +} + +# mod.ts +import 'jsr:@scope/a' + +# output +{ + "roots": [ + "file:///mod.ts" + ], + "modules": [ + { + "kind": "esm", + "dependencies": [ + { + "specifier": "jsr:@scope/a", + "code": { + "specifier": "jsr:@scope/a", + "span": { + "start": { + "line": 0, + "character": 7 + }, + "end": { + "line": 0, + "character": 21 + } + } + } + } + ], + "size": 22, + "mediaType": "TypeScript", + "specifier": "file:///mod.ts" + }, + { + "kind": "esm", + "size": 549, + "mediaType": "TypeScript", + "specifier": "https://jsr.io/@scope/a/1.0.0/mod.ts" + } + ], + "redirects": { + "jsr:@scope/a": "https://jsr.io/@scope/a/1.0.0/mod.ts" + }, + "packages": { + "@scope/a": "@scope/a@1.0.0" + } +} + +Fast check https://jsr.io/@scope/a/1.0.0/mod.ts: + {} + export class argsToArray { + argsToArray(..._args: string[]): void; + argsToArray(..._args: number[]): void; + argsToArray(...param0?: any): any { + return {} as never; + } + } + export function overloadSpread(...args: string[]); + export function overloadSpread(...args: number[]); + 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 { + return {} as never; + } + --- DTS --- + export declare class argsToArray { + 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[]);