Use mapped rest type member when expanding rest parameter names (#39317)

* Use mapped rest type member when expanding rest parameter names

* Add test for #39228 which is also fixed by parameters having unique names
This commit is contained in:
Wesley Wigham
2020-06-29 12:30:23 -07:00
committed by GitHub
parent ee5c3fa57d
commit 99bec5067b
6 changed files with 137 additions and 4 deletions

View File

@@ -9781,7 +9781,7 @@ namespace ts {
const restParams = map(elementTypes, (t, i) => {
// Lookup the label from the individual tuple passed in before falling back to the signature `rest` parameter name
const tupleLabelName = !!associatedNames && getTupleElementLabel(associatedNames[i]);
const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i);
const name = tupleLabelName || getParameterNameAtPosition(sig, restIndex + i, restType);
const flags = restType.target.elementFlags[i];
const checkFlags = flags & ElementFlags.Variable ? CheckFlags.RestParameter :
flags & ElementFlags.Optional ? CheckFlags.OptionalParameter : 0;
@@ -27708,13 +27708,13 @@ namespace ts {
return d.name.escapedText;
}
function getParameterNameAtPosition(signature: Signature, pos: number) {
function getParameterNameAtPosition(signature: Signature, pos: number, overrideRestType?: Type) {
const paramCount = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0);
if (pos < paramCount) {
return signature.parameters[pos].escapedName;
}
const restParameter = signature.parameters[paramCount] || unknownSymbol;
const restType = getTypeOfSymbol(restParameter);
const restType = overrideRestType || getTypeOfSymbol(restParameter);
if (isTupleType(restType)) {
const associatedNames = (<TupleType>(<TypeReference>restType).target).labeledElementDeclarations;
const index = pos - paramCount;

View File

@@ -1426,7 +1426,7 @@ namespace FourSlash {
this.raiseError("Could not get a help signature");
}
const selectedItem = help.items[help.selectedItemIndex];
const selectedItem = help.items[options.overrideSelectedItemIndex ?? help.selectedItemIndex];
// Argument index may exceed number of parameters
const currentParameter = selectedItem.parameters[help.argumentIndex] as ts.SignatureHelpParameter | undefined;
@@ -1478,6 +1478,7 @@ namespace FourSlash {
"isVariadic",
"tags",
"argumentCount",
"overrideSelectedItemIndex"
];
for (const key in options) {
if (!ts.contains(allKeys, key)) {

View File

@@ -1533,6 +1533,7 @@ namespace FourSlashInterface {
/** @default ts.emptyArray */
readonly tags?: readonly ts.JSDocTagInfo[];
readonly triggerReason?: ts.SignatureHelpTriggerReason;
readonly overrideSelectedItemIndex?: number;
}
export interface VerifyNavigateToOptions {

View File

@@ -644,6 +644,7 @@ declare namespace FourSlashInterface {
isVariadic?: boolean;
tags?: ReadonlyArray<JSDocTagInfo>;
triggerReason?: SignatureHelpTriggerReason;
overrideSelectedItemIndex?: number;
}
export type SignatureHelpTriggerReason =

View File

@@ -0,0 +1,36 @@
/// <reference path='fourslash.ts' />
////export function complex(item: string, another: string, ...rest: [] | [object, (err: Error) => void] | [(err: Error) => void, ...object[]]) {
////
////}
////
////complex(/*1*/);
////complex("ok", "ok", /*2*/);
////complex("ok", "ok", e => void e, {}, /*3*/);
verify.signatureHelp(
{
marker: "1",
text: "complex(item: string, another: string): void",
overloadsCount: 3,
parameterCount: 2,
parameterName: "item",
parameterSpan: "item: string",
isVariadic: false,
},
{
marker: "2",
text: "complex(item: string, another: string, rest_0: object, rest_1: (err: Error) => void): void",
overloadsCount: 3,
parameterCount: 4,
parameterName: "rest_0",
parameterSpan: "rest_0: object",
isVariadic: false,
},
{
marker: "3",
text: "complex(item: string, another: string, rest_0: (err: Error) => void, ...rest_1: object[]): void",
overloadsCount: 3,
isVariadic: true,
},
);

View File

@@ -0,0 +1,94 @@
/// <reference path='fourslash.ts' />
////function foo(...args: [string, string] | [number, string, string]
////) {
////
////}
////
////foo(123/*1*/,)
////foo(""/*2*/, ""/*3*/)
////foo(123/*4*/, ""/*5*/, )
////foo(123/*6*/, ""/*7*/, ""/*8*/)
verify.signatureHelp(
{
marker: "1",
text: "foo(args_0: number, args_1: string, args_2: string): void",
overloadsCount: 2,
parameterCount: 3,
parameterName: "args_0",
parameterSpan: "args_0: number",
isVariadic: false,
overrideSelectedItemIndex: 1
},
{
marker: "2",
text: "foo(args_0: string, args_1: string): void",
overloadsCount: 2,
parameterCount: 2,
parameterName: "args_0",
parameterSpan: "args_0: string",
isVariadic: false,
overrideSelectedItemIndex: 0
},
{
marker: "3",
text: "foo(args_0: string, args_1: string): void",
overloadsCount: 2,
parameterCount: 2,
parameterName: "args_1",
parameterSpan: "args_1: string",
isVariadic: false,
overrideSelectedItemIndex: 0
},
{
marker: "4",
text: "foo(args_0: number, args_1: string, args_2: string): void",
overloadsCount: 2,
parameterCount: 3,
parameterName: "args_0",
parameterSpan: "args_0: number",
isVariadic: false,
overrideSelectedItemIndex: 1
},
{
marker: "5",
text: "foo(args_0: number, args_1: string, args_2: string): void",
overloadsCount: 2,
parameterCount: 3,
parameterName: "args_1",
parameterSpan: "args_1: string",
isVariadic: false,
overrideSelectedItemIndex: 1
},
{
marker: "6",
text: "foo(args_0: number, args_1: string, args_2: string): void",
overloadsCount: 2,
parameterCount: 3,
parameterName: "args_0",
parameterSpan: "args_0: number",
isVariadic: false,
overrideSelectedItemIndex: 1
},
{
marker: "7",
text: "foo(args_0: number, args_1: string, args_2: string): void",
overloadsCount: 2,
parameterCount: 3,
parameterName: "args_1",
parameterSpan: "args_1: string",
isVariadic: false,
overrideSelectedItemIndex: 1
},
{
marker: "8",
text: "foo(args_0: number, args_1: string, args_2: string): void",
overloadsCount: 2,
parameterCount: 3,
parameterName: "args_2",
parameterSpan: "args_2: string",
isVariadic: false,
overrideSelectedItemIndex: 1
},
);