From fe82a610cdb3e3125e26b345d5f7fa7e35687407 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Thu, 31 Aug 2023 01:17:43 +0300 Subject: [PATCH] fix(55014): Quick fix for ts7051 introduces incorrect type (#55020) --- .../codefixes/addNameToNamelessParameter.ts | 36 ++++++++++++++++--- .../fourslash/codeFixAddParameterNames4.ts | 9 +++++ .../fourslash/codeFixAddParameterNames5.ts | 9 +++++ .../fourslash/codeFixAddParameterNames6.ts | 10 ++++++ 4 files changed, 59 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/codeFixAddParameterNames4.ts create mode 100644 tests/cases/fourslash/codeFixAddParameterNames5.ts create mode 100644 tests/cases/fourslash/codeFixAddParameterNames6.ts 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) {}`, +});