mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
fix(48260): Incorrect parameter hint is highlighted when arguments contain spread syntax (#56372)
Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
@@ -3122,7 +3122,7 @@ function getContextualType(previousToken: Node, position: number, sourceFile: So
|
||||
case SyntaxKind.OpenBraceToken:
|
||||
return isJsxExpression(parent) && !isJsxElement(parent.parent) && !isJsxFragment(parent.parent) ? checker.getContextualTypeForJsxAttribute(parent.parent) : undefined;
|
||||
default:
|
||||
const argInfo = SignatureHelp.getArgumentInfoForCompletions(previousToken, position, sourceFile);
|
||||
const argInfo = SignatureHelp.getArgumentInfoForCompletions(previousToken, position, sourceFile, checker);
|
||||
return argInfo ?
|
||||
// At `,`, treat this as the next argument after the comma.
|
||||
checker.getContextualTypeForArgumentAtIndex(argInfo.invocation, argInfo.argumentIndex + (previousToken.kind === SyntaxKind.CommaToken ? 1 : 0)) :
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
createTextSpanFromBounds,
|
||||
createTextSpanFromNode,
|
||||
Debug,
|
||||
ElementFlags,
|
||||
EmitHint,
|
||||
emptyArray,
|
||||
Expression,
|
||||
@@ -49,6 +50,7 @@ import {
|
||||
isPropertyAccessExpression,
|
||||
isSourceFile,
|
||||
isSourceFileJS,
|
||||
isSpreadElement,
|
||||
isTaggedTemplateExpression,
|
||||
isTemplateHead,
|
||||
isTemplateLiteralToken,
|
||||
@@ -58,6 +60,7 @@ import {
|
||||
JsxTagNameExpression,
|
||||
last,
|
||||
lastOrUndefined,
|
||||
length,
|
||||
ListFormat,
|
||||
map,
|
||||
mapToDisplayParts,
|
||||
@@ -77,6 +80,7 @@ import {
|
||||
skipTrivia,
|
||||
SourceFile,
|
||||
spacePart,
|
||||
SpreadElement,
|
||||
Symbol,
|
||||
SymbolDisplayPart,
|
||||
symbolToDisplayParts,
|
||||
@@ -85,6 +89,7 @@ import {
|
||||
TemplateExpression,
|
||||
TextSpan,
|
||||
tryCast,
|
||||
TupleTypeReference,
|
||||
Type,
|
||||
TypeChecker,
|
||||
TypeParameter,
|
||||
@@ -272,25 +277,25 @@ export interface ArgumentInfoForCompletions {
|
||||
readonly argumentCount: number;
|
||||
}
|
||||
/** @internal */
|
||||
export function getArgumentInfoForCompletions(node: Node, position: number, sourceFile: SourceFile): ArgumentInfoForCompletions | undefined {
|
||||
const info = getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||
export function getArgumentInfoForCompletions(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): ArgumentInfoForCompletions | undefined {
|
||||
const info = getImmediatelyContainingArgumentInfo(node, position, sourceFile, checker);
|
||||
return !info || info.isTypeParameterList || info.invocation.kind !== InvocationKind.Call ? undefined
|
||||
: { invocation: info.invocation.node, argumentCount: info.argumentCount, argumentIndex: info.argumentIndex };
|
||||
}
|
||||
|
||||
function getArgumentOrParameterListInfo(node: Node, position: number, sourceFile: SourceFile): { readonly list: Node; readonly argumentIndex: number; readonly argumentCount: number; readonly argumentsSpan: TextSpan; } | undefined {
|
||||
const info = getArgumentOrParameterListAndIndex(node, sourceFile);
|
||||
function getArgumentOrParameterListInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): { readonly list: Node; readonly argumentIndex: number; readonly argumentCount: number; readonly argumentsSpan: TextSpan; } | undefined {
|
||||
const info = getArgumentOrParameterListAndIndex(node, sourceFile, checker);
|
||||
if (!info) return undefined;
|
||||
const { list, argumentIndex } = info;
|
||||
|
||||
const argumentCount = getArgumentCount(list, /*ignoreTrailingComma*/ isInString(sourceFile, position, node));
|
||||
const argumentCount = getArgumentCount(list, /*ignoreTrailingComma*/ isInString(sourceFile, position, node), checker);
|
||||
if (argumentIndex !== 0) {
|
||||
Debug.assertLessThan(argumentIndex, argumentCount);
|
||||
}
|
||||
const argumentsSpan = getApplicableSpanForArguments(list, sourceFile);
|
||||
return { list, argumentIndex, argumentCount, argumentsSpan };
|
||||
}
|
||||
function getArgumentOrParameterListAndIndex(node: Node, sourceFile: SourceFile): { readonly list: Node; readonly argumentIndex: number; } | undefined {
|
||||
function getArgumentOrParameterListAndIndex(node: Node, sourceFile: SourceFile, checker: TypeChecker): { readonly list: Node; readonly argumentIndex: number; } | undefined {
|
||||
if (node.kind === SyntaxKind.LessThanToken || node.kind === SyntaxKind.OpenParenToken) {
|
||||
// Find the list that starts right *after* the < or ( token.
|
||||
// If the user has just opened a list, consider this item 0.
|
||||
@@ -304,7 +309,7 @@ function getArgumentOrParameterListAndIndex(node: Node, sourceFile: SourceFile):
|
||||
// - On the target of the call (parent.func)
|
||||
// - On the 'new' keyword in a 'new' expression
|
||||
const list = findContainingList(node);
|
||||
return list && { list, argumentIndex: getArgumentIndex(list, node) };
|
||||
return list && { list, argumentIndex: getArgumentIndex(list, node, checker) };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +317,7 @@ function getArgumentOrParameterListAndIndex(node: Node, sourceFile: SourceFile):
|
||||
* Returns relevant information for the argument list and the current argument if we are
|
||||
* in the argument of an invocation; returns undefined otherwise.
|
||||
*/
|
||||
function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile): ArgumentListInfo | undefined {
|
||||
function getImmediatelyContainingArgumentInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): ArgumentListInfo | undefined {
|
||||
const { parent } = node;
|
||||
if (isCallOrNewExpression(parent)) {
|
||||
const invocation = parent;
|
||||
@@ -331,7 +336,7 @@ function getImmediatelyContainingArgumentInfo(node: Node, position: number, sour
|
||||
// Case 3:
|
||||
// foo<T#, U#>(a#, #b#) -> The token is buried inside a list, and should give signature help
|
||||
// Find out if 'node' is an argument, a type argument, or neither
|
||||
const info = getArgumentOrParameterListInfo(node, position, sourceFile);
|
||||
const info = getArgumentOrParameterListInfo(node, position, sourceFile, checker);
|
||||
if (!info) return undefined;
|
||||
const { list, argumentIndex, argumentCount, argumentsSpan } = info;
|
||||
const isTypeParameterList = !!parent.typeArguments && parent.typeArguments.pos === list.pos;
|
||||
@@ -397,7 +402,7 @@ function getImmediatelyContainingArgumentInfo(node: Node, position: number, sour
|
||||
}
|
||||
|
||||
function getImmediatelyContainingArgumentOrContextualParameterInfo(node: Node, position: number, sourceFile: SourceFile, checker: TypeChecker): ArgumentListInfo | undefined {
|
||||
return tryGetParameterInfo(node, position, sourceFile, checker) || getImmediatelyContainingArgumentInfo(node, position, sourceFile);
|
||||
return tryGetParameterInfo(node, position, sourceFile, checker) || getImmediatelyContainingArgumentInfo(node, position, sourceFile, checker);
|
||||
}
|
||||
|
||||
function getHighestBinary(b: BinaryExpression): BinaryExpression {
|
||||
@@ -452,7 +457,7 @@ function getContextualSignatureLocationInfo(node: Node, sourceFile: SourceFile,
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
case SyntaxKind.FunctionExpression:
|
||||
case SyntaxKind.ArrowFunction:
|
||||
const info = getArgumentOrParameterListInfo(node, position, sourceFile);
|
||||
const info = getArgumentOrParameterListInfo(node, position, sourceFile, checker);
|
||||
if (!info) return undefined;
|
||||
const { argumentIndex, argumentCount, argumentsSpan } = info;
|
||||
const contextualType = isMethodDeclaration(parent) ? checker.getContextualTypeForObjectLiteralElement(parent) : checker.getContextualType(parent as ParenthesizedExpression | FunctionExpression | ArrowFunction);
|
||||
@@ -476,7 +481,7 @@ function chooseBetterSymbol(s: Symbol): Symbol {
|
||||
: s;
|
||||
}
|
||||
|
||||
function getArgumentIndex(argumentsList: Node, node: Node) {
|
||||
function getArgumentIndex(argumentsList: Node, node: Node, checker: TypeChecker) {
|
||||
// The list we got back can include commas. In the presence of errors it may
|
||||
// also just have nodes without commas. For example "Foo(a b c)" will have 3
|
||||
// args without commas. We want to find what index we're at. So we count
|
||||
@@ -488,20 +493,39 @@ function getArgumentIndex(argumentsList: Node, node: Node) {
|
||||
// on. In that case, even if we're after the trailing comma, we'll still see
|
||||
// that trailing comma in the list, and we'll have generated the appropriate
|
||||
// arg index.
|
||||
const args = argumentsList.getChildren();
|
||||
let argumentIndex = 0;
|
||||
for (const child of argumentsList.getChildren()) {
|
||||
for (let pos = 0; pos < length(args); pos++) {
|
||||
const child = args[pos];
|
||||
if (child === node) {
|
||||
break;
|
||||
}
|
||||
if (child.kind !== SyntaxKind.CommaToken) {
|
||||
argumentIndex++;
|
||||
if (isSpreadElement(child)) {
|
||||
argumentIndex = argumentIndex + getSpreadElementCount(child, checker) + (pos > 0 ? pos : 0);
|
||||
}
|
||||
else {
|
||||
if (child.kind !== SyntaxKind.CommaToken) {
|
||||
argumentIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return argumentIndex;
|
||||
}
|
||||
|
||||
function getArgumentCount(argumentsList: Node, ignoreTrailingComma: boolean) {
|
||||
function getSpreadElementCount(node: SpreadElement, checker: TypeChecker) {
|
||||
const spreadType = checker.getTypeAtLocation(node.expression);
|
||||
if (checker.isTupleType(spreadType)) {
|
||||
const { elementFlags, fixedLength } = (spreadType as TupleTypeReference).target;
|
||||
if (fixedLength === 0) {
|
||||
return 0;
|
||||
}
|
||||
const firstOptionalIndex = findIndex(elementFlags, f => !(f & ElementFlags.Required));
|
||||
return firstOptionalIndex < 0 ? fixedLength : firstOptionalIndex;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function getArgumentCount(argumentsList: Node, ignoreTrailingComma: boolean, checker: TypeChecker) {
|
||||
// The argument count for a list is normally the number of non-comma children it has.
|
||||
// For example, if you have "Foo(a,b)" then there will be three children of the arg
|
||||
// list 'a' '<comma>' 'b'. So, in this case the arg count will be 2. However, there
|
||||
@@ -515,7 +539,14 @@ function getArgumentCount(argumentsList: Node, ignoreTrailingComma: boolean) {
|
||||
// arg count of 3.
|
||||
const listChildren = argumentsList.getChildren();
|
||||
|
||||
let argumentCount = countWhere(listChildren, arg => arg.kind !== SyntaxKind.CommaToken);
|
||||
let argumentCount = 0;
|
||||
for (const child of listChildren) {
|
||||
if (isSpreadElement(child)) {
|
||||
argumentCount = argumentCount + getSpreadElementCount(child, checker);
|
||||
}
|
||||
}
|
||||
|
||||
argumentCount = argumentCount + countWhere(listChildren, arg => arg.kind !== SyntaxKind.CommaToken);
|
||||
if (!ignoreTrailingComma && listChildren.length > 0 && last(listChildren).kind === SyntaxKind.CommaToken) {
|
||||
argumentCount++;
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ function getStringLiteralCompletionEntries(sourceFile: SourceFile, node: StringL
|
||||
case SyntaxKind.NewExpression:
|
||||
case SyntaxKind.JsxAttribute:
|
||||
if (!isRequireCallArgument(node) && !isImportCall(parent)) {
|
||||
const argumentInfo = SignatureHelp.getArgumentInfoForCompletions(parent.kind === SyntaxKind.JsxAttribute ? parent.parent : node, position, sourceFile);
|
||||
const argumentInfo = SignatureHelp.getArgumentInfoForCompletions(parent.kind === SyntaxKind.JsxAttribute ? parent.parent : node, position, sourceFile, typeChecker);
|
||||
// Get string literal completions from specialized signatures of the target
|
||||
// i.e. declare function f(a: 'A');
|
||||
// f("/*completion position*/")
|
||||
|
||||
709
tests/baselines/reference/signatureHelpRestArgs.baseline
Normal file
709
tests/baselines/reference/signatureHelpRestArgs.baseline
Normal file
@@ -0,0 +1,709 @@
|
||||
// === SignatureHelp ===
|
||||
=== /tests/cases/fourslash/signatureHelpRestArgs.ts ===
|
||||
// function fn(a: number, b: number, c: number) {}
|
||||
// const a = [1, 2] as const;
|
||||
// const b = [1] as const;
|
||||
//
|
||||
// fn(...a, );
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | fn(a: number, b: number, **c: number**): void
|
||||
// | ----------------------------------------------------------------------
|
||||
// fn(, ...a);
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | fn(**a: number**, b: number, c: number): void
|
||||
// | ----------------------------------------------------------------------
|
||||
//
|
||||
// fn(...b, );
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | fn(a: number, **b: number**, c: number): void
|
||||
// | ----------------------------------------------------------------------
|
||||
// fn(, ...b, );
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | fn(**a: number**, b: number, c: number): void
|
||||
// | ----------------------------------------------------------------------
|
||||
// ^
|
||||
// | ----------------------------------------------------------------------
|
||||
// | fn(a: number, b: number, **c: number**): void
|
||||
// | ----------------------------------------------------------------------
|
||||
|
||||
[
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/signatureHelpRestArgs.ts",
|
||||
"position": 109,
|
||||
"name": "1"
|
||||
},
|
||||
"item": {
|
||||
"items": [
|
||||
{
|
||||
"isVariadic": false,
|
||||
"prefixDisplayParts": [
|
||||
{
|
||||
"text": "fn",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
}
|
||||
],
|
||||
"suffixDisplayParts": [
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "void",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"separatorDisplayParts": [
|
||||
{
|
||||
"text": ",",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "a",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "a",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "b",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "c",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "c",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"applicableSpan": {
|
||||
"start": 103,
|
||||
"length": 6
|
||||
},
|
||||
"selectedItemIndex": 0,
|
||||
"argumentIndex": 2,
|
||||
"argumentCount": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/signatureHelpRestArgs.ts",
|
||||
"position": 115,
|
||||
"name": "2"
|
||||
},
|
||||
"item": {
|
||||
"items": [
|
||||
{
|
||||
"isVariadic": false,
|
||||
"prefixDisplayParts": [
|
||||
{
|
||||
"text": "fn",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
}
|
||||
],
|
||||
"suffixDisplayParts": [
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "void",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"separatorDisplayParts": [
|
||||
{
|
||||
"text": ",",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "a",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "a",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "b",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "c",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "c",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"applicableSpan": {
|
||||
"start": 115,
|
||||
"length": 6
|
||||
},
|
||||
"selectedItemIndex": 0,
|
||||
"argumentIndex": 0,
|
||||
"argumentCount": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/signatureHelpRestArgs.ts",
|
||||
"position": 134,
|
||||
"name": "3"
|
||||
},
|
||||
"item": {
|
||||
"items": [
|
||||
{
|
||||
"isVariadic": false,
|
||||
"prefixDisplayParts": [
|
||||
{
|
||||
"text": "fn",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
}
|
||||
],
|
||||
"suffixDisplayParts": [
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "void",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"separatorDisplayParts": [
|
||||
{
|
||||
"text": ",",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "a",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "a",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "b",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "c",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "c",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"applicableSpan": {
|
||||
"start": 128,
|
||||
"length": 6
|
||||
},
|
||||
"selectedItemIndex": 0,
|
||||
"argumentIndex": 1,
|
||||
"argumentCount": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/signatureHelpRestArgs.ts",
|
||||
"position": 140,
|
||||
"name": "4"
|
||||
},
|
||||
"item": {
|
||||
"items": [
|
||||
{
|
||||
"isVariadic": false,
|
||||
"prefixDisplayParts": [
|
||||
{
|
||||
"text": "fn",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
}
|
||||
],
|
||||
"suffixDisplayParts": [
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "void",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"separatorDisplayParts": [
|
||||
{
|
||||
"text": ",",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "a",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "a",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "b",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "c",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "c",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"applicableSpan": {
|
||||
"start": 140,
|
||||
"length": 8
|
||||
},
|
||||
"selectedItemIndex": 0,
|
||||
"argumentIndex": 0,
|
||||
"argumentCount": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"marker": {
|
||||
"fileName": "/tests/cases/fourslash/signatureHelpRestArgs.ts",
|
||||
"position": 148,
|
||||
"name": "5"
|
||||
},
|
||||
"item": {
|
||||
"items": [
|
||||
{
|
||||
"isVariadic": false,
|
||||
"prefixDisplayParts": [
|
||||
{
|
||||
"text": "fn",
|
||||
"kind": "functionName"
|
||||
},
|
||||
{
|
||||
"text": "(",
|
||||
"kind": "punctuation"
|
||||
}
|
||||
],
|
||||
"suffixDisplayParts": [
|
||||
{
|
||||
"text": ")",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "void",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"separatorDisplayParts": [
|
||||
{
|
||||
"text": ",",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
}
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "a",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "a",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "b",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "b",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
},
|
||||
{
|
||||
"name": "c",
|
||||
"documentation": [],
|
||||
"displayParts": [
|
||||
{
|
||||
"text": "c",
|
||||
"kind": "parameterName"
|
||||
},
|
||||
{
|
||||
"text": ":",
|
||||
"kind": "punctuation"
|
||||
},
|
||||
{
|
||||
"text": " ",
|
||||
"kind": "space"
|
||||
},
|
||||
{
|
||||
"text": "number",
|
||||
"kind": "keyword"
|
||||
}
|
||||
],
|
||||
"isOptional": false,
|
||||
"isRest": false
|
||||
}
|
||||
],
|
||||
"documentation": [],
|
||||
"tags": []
|
||||
}
|
||||
],
|
||||
"applicableSpan": {
|
||||
"start": 140,
|
||||
"length": 8
|
||||
},
|
||||
"selectedItemIndex": 0,
|
||||
"argumentIndex": 2,
|
||||
"argumentCount": 3
|
||||
}
|
||||
}
|
||||
]
|
||||
13
tests/cases/fourslash/signatureHelpRestArgs.ts
Normal file
13
tests/cases/fourslash/signatureHelpRestArgs.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
////function fn(a: number, b: number, c: number) {}
|
||||
////const a = [1, 2] as const;
|
||||
////const b = [1] as const;
|
||||
////
|
||||
////fn(...a, /*1*/);
|
||||
////fn(/*2*/, ...a);
|
||||
////
|
||||
////fn(...b, /*3*/);
|
||||
////fn(/*4*/, ...b, /*5*/);
|
||||
|
||||
verify.baselineSignatureHelp();
|
||||
Reference in New Issue
Block a user