From 3f92a6498f4b404f0c4804a0061f1ea60448a563 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Tue, 3 Nov 2020 01:20:13 +0200 Subject: [PATCH] fix(40257): fix type parameters range (#40265) --- src/compiler/checker.ts | 5 +++-- src/compiler/utilities.ts | 6 ++++-- src/services/textChanges.ts | 2 +- .../fourslash/unusedTypeParametersWithTrivia1.ts | 12 ++++++++++++ .../fourslash/unusedTypeParametersWithTrivia2.ts | 9 +++++++++ .../fourslash/unusedTypeParametersWithTrivia3.ts | 9 +++++++++ .../fourslash/unusedTypeParametersWithTrivia4.ts | 12 ++++++++++++ 7 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/unusedTypeParametersWithTrivia1.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersWithTrivia2.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersWithTrivia3.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersWithTrivia4.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c5b129c629..ad1400cd06 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33329,15 +33329,16 @@ namespace ts { const { parent } = typeParameter; if (parent.kind !== SyntaxKind.InferType && parent.typeParameters!.every(isTypeParameterUnused)) { if (tryAddToSet(seenParentsWithEveryUnused, parent)) { + const sourceFile = getSourceFileOfNode(parent); const range = isJSDocTemplateTag(parent) // Whole @template tag ? rangeOfNode(parent) // Include the `<>` in the error message - : rangeOfTypeParameters(parent.typeParameters!); + : rangeOfTypeParameters(sourceFile, parent.typeParameters!); const only = parent.typeParameters!.length === 1; const message = only ? Diagnostics._0_is_declared_but_its_value_is_never_read : Diagnostics.All_type_parameters_are_unused; const arg0 = only ? name : undefined; - addDiagnostic(typeParameter, UnusedKind.Parameter, createFileDiagnostic(getSourceFileOfNode(parent), range.pos, range.end - range.pos, message, arg0)); + addDiagnostic(typeParameter, UnusedKind.Parameter, createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, message, arg0)); } } else { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 2dc1fb0475..d68ba6ef8b 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -6709,9 +6709,11 @@ namespace ts { return { pos: getTokenPosOfNode(node), end: node.end }; } - export function rangeOfTypeParameters(typeParameters: NodeArray): TextRange { + export function rangeOfTypeParameters(sourceFile: SourceFile, typeParameters: NodeArray): TextRange { // Include the `<>` - return { pos: typeParameters.pos - 1, end: typeParameters.end + 1 }; + const pos = typeParameters.pos - 1; + const end = skipTrivia(sourceFile.text, typeParameters.end) + 1; + return { pos, end }; } export interface HostWithIsSourceOfProjectReferenceRedirect { diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 17f5ee4adf..9bc3b50c8d 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -843,7 +843,7 @@ namespace ts.textChanges { for (const { sourceFile, node } of this.deletedNodes) { if (!this.deletedNodes.some(d => d.sourceFile === sourceFile && rangeContainsRangeExclusive(d.node, node))) { if (isArray(node)) { - this.deleteRange(sourceFile, rangeOfTypeParameters(node)); + this.deleteRange(sourceFile, rangeOfTypeParameters(sourceFile, node)); } else { deleteDeclaration.deleteDeclaration(this, deletedNodesInLists, sourceFile, node); diff --git a/tests/cases/fourslash/unusedTypeParametersWithTrivia1.ts b/tests/cases/fourslash/unusedTypeParametersWithTrivia1.ts new file mode 100644 index 0000000000..ab549e9202 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersWithTrivia1.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedParameters: true +////export type Foo< +//// T1 extends any, +//// T2 extends any +////> = () => void; + +verify.codeFix({ + description: ts.Diagnostics.Remove_type_parameters.message, + newFileContent: "export type Foo = () => void;" +}); diff --git a/tests/cases/fourslash/unusedTypeParametersWithTrivia2.ts b/tests/cases/fourslash/unusedTypeParametersWithTrivia2.ts new file mode 100644 index 0000000000..7ea2691c97 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersWithTrivia2.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedParameters: true +////export type Foo< T1 extends any, T2 extends any > = () => void; + +verify.codeFix({ + description: ts.Diagnostics.Remove_type_parameters.message, + newFileContent: "export type Foo = () => void;" +}); diff --git a/tests/cases/fourslash/unusedTypeParametersWithTrivia3.ts b/tests/cases/fourslash/unusedTypeParametersWithTrivia3.ts new file mode 100644 index 0000000000..2c86d2fc3d --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersWithTrivia3.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedParameters: true +////export type Foo = () => void; + +verify.codeFix({ + description: ts.Diagnostics.Remove_type_parameters.message, + newFileContent: "export type Foo = () => void;" +}); diff --git a/tests/cases/fourslash/unusedTypeParametersWithTrivia4.ts b/tests/cases/fourslash/unusedTypeParametersWithTrivia4.ts new file mode 100644 index 0000000000..90031c8fc5 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersWithTrivia4.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedParameters: true +////export type Foo< +//// T1 extends any, +//// T2 extends any +//// /* comment */> = () => void; + +verify.codeFix({ + description: ts.Diagnostics.Remove_type_parameters.message, + newFileContent: "export type Foo = () => void;" +});