diff --git a/src/services/codefixes/addNameToNamelessParameter.ts b/src/services/codefixes/addNameToNamelessParameter.ts
index a4d662fa913..ca55406e9ca 100644
--- a/src/services/codefixes/addNameToNamelessParameter.ts
+++ b/src/services/codefixes/addNameToNamelessParameter.ts
@@ -1,12 +1,19 @@
import {
+ createRange,
Debug,
Diagnostics,
factory,
+ findNextToken,
getTokenAtPosition,
Identifier,
+ isArrayBindingPattern,
+ isArrayTypeNode,
isParameter,
+ ParameterDeclaration,
SourceFile,
+ SyntaxKind,
textChanges,
+ TypeNode,
} from "../_namespaces/ts";
import {
codeFixAll,
@@ -26,8 +33,8 @@ registerCodeFix({
getAllCodeActions: context => codeFixAll(context, errorCodes, (changes, diag) => makeChange(changes, diag.file, diag.start)),
});
-function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
- const token = getTokenAtPosition(sourceFile, pos);
+function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, start: number) {
+ const token = getTokenAtPosition(sourceFile, start);
const param = token.parent;
if (!isParameter(param)) {
return Debug.fail("Tried to add a parameter name to a non-parameter: " + Debug.formatSyntaxKind(token.kind));
@@ -37,14 +44,33 @@ function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: Source
Debug.assert(!param.type, "Tried to add a parameter name to a parameter that already had one.");
Debug.assert(i > -1, "Parameter not found in parent parameter list.");
- const typeNode = factory.createTypeReferenceNode(param.name as Identifier, /*typeArguments*/ undefined);
+ let end = param.name.getEnd();
+ let typeNode: TypeNode = factory.createTypeReferenceNode(param.name as Identifier, /*typeArguments*/ undefined);
+ let nextParam = tryGetNextParam(sourceFile, param);
+ while (nextParam) {
+ typeNode = factory.createArrayTypeNode(typeNode);
+ end = nextParam.getEnd();
+ nextParam = tryGetNextParam(sourceFile, nextParam);
+ }
+
const replacement = factory.createParameterDeclaration(
param.modifiers,
param.dotDotDotToken,
"arg" + i,
param.questionToken,
- param.dotDotDotToken ? factory.createArrayTypeNode(typeNode) : typeNode,
+ param.dotDotDotToken && !isArrayTypeNode(typeNode) ? factory.createArrayTypeNode(typeNode) : typeNode,
param.initializer,
);
- changeTracker.replaceNode(sourceFile, param, replacement);
+ changeTracker.replaceRange(sourceFile, createRange(param.getStart(sourceFile), end), replacement);
+}
+
+function tryGetNextParam(sourceFile: SourceFile, param: ParameterDeclaration) {
+ const nextToken = findNextToken(param.name, param.parent, sourceFile);
+ if (
+ nextToken && nextToken.kind === SyntaxKind.OpenBracketToken
+ && isArrayBindingPattern(nextToken.parent) && isParameter(nextToken.parent.parent)
+ ) {
+ return nextToken.parent.parent;
+ }
+ return undefined;
}
diff --git a/tests/cases/fourslash/codeFixAddParameterNames4.ts b/tests/cases/fourslash/codeFixAddParameterNames4.ts
new file mode 100644
index 00000000000..fdd10c863cf
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddParameterNames4.ts
@@ -0,0 +1,9 @@
+///
+
+// @noImplicitAny: true
+////function fn(f: (...number[]) => unknown) {}
+
+verify.codeFix({
+ description: ts.Diagnostics.Add_parameter_name.message,
+ newFileContent: `function fn(f: (...arg0: number[]) => unknown) {}`,
+});
diff --git a/tests/cases/fourslash/codeFixAddParameterNames5.ts b/tests/cases/fourslash/codeFixAddParameterNames5.ts
new file mode 100644
index 00000000000..e0b80e2a0d6
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddParameterNames5.ts
@@ -0,0 +1,9 @@
+///
+
+// @noImplicitAny: true
+////function fn(f: (...number[][][]) => unknown) {}
+
+verify.codeFix({
+ description: ts.Diagnostics.Add_parameter_name.message,
+ newFileContent: `function fn(f: (...arg0: number[][][]) => unknown) {}`,
+});
diff --git a/tests/cases/fourslash/codeFixAddParameterNames6.ts b/tests/cases/fourslash/codeFixAddParameterNames6.ts
new file mode 100644
index 00000000000..dc9dab49c7f
--- /dev/null
+++ b/tests/cases/fourslash/codeFixAddParameterNames6.ts
@@ -0,0 +1,10 @@
+///
+
+// @noImplicitAny: true
+////function fn(f: (...number) => unknown) {}
+
+verify.codeFix({
+ index: 0,
+ description: ts.Diagnostics.Add_parameter_name.message,
+ newFileContent: `function fn(f: (...arg0: number[]) => unknown) {}`,
+});