From b2ca04baafb578170a87ede1f5729a297398dc28 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Wed, 2 May 2018 08:43:00 -0700 Subject: [PATCH 1/2] Handle BindingElement in fixUnusedIdentifier --- src/services/codefixes/fixUnusedIdentifier.ts | 4 +++ src/services/formatting/smartIndenter.ts | 20 ++++++++------ ...usedIdentifier_destructure_partlyUnused.ts | 26 +++++++++++++++++++ 3 files changed, 42 insertions(+), 8 deletions(-) create mode 100644 tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index fd360c73ea1ad..8a160fbfb60e0 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -171,6 +171,10 @@ namespace ts.codefix { } break; + case SyntaxKind.BindingElement: + changes.deleteNodeInList(sourceFile, parent); + break; + // handle case where 'import a = A;' case SyntaxKind.ImportEqualsDeclaration: const importEquals = getAncestor(identifier, SyntaxKind.ImportEqualsDeclaration); diff --git a/src/services/formatting/smartIndenter.ts b/src/services/formatting/smartIndenter.ts index a82f11f239bfd..0e89be425328c 100644 --- a/src/services/formatting/smartIndenter.ts +++ b/src/services/formatting/smartIndenter.ts @@ -327,9 +327,10 @@ namespace ts.formatting { export function getContainingList(node: Node, sourceFile: SourceFile): NodeArray { if (node.parent) { + const { end } = node; switch (node.parent.kind) { case SyntaxKind.TypeReference: - return getListIfStartEndIsInListRange((node.parent).typeArguments, node.getStart(sourceFile), node.getEnd()); + return getListIfStartEndIsInListRange((node.parent).typeArguments, node.getStart(sourceFile), end); case SyntaxKind.ObjectLiteralExpression: return (node.parent).properties; case SyntaxKind.ArrayLiteralExpression: @@ -344,22 +345,25 @@ namespace ts.formatting { case SyntaxKind.ConstructorType: case SyntaxKind.ConstructSignature: { const start = node.getStart(sourceFile); - return getListIfStartEndIsInListRange((node.parent).typeParameters, start, node.getEnd()) || - getListIfStartEndIsInListRange((node.parent).parameters, start, node.getEnd()); + return getListIfStartEndIsInListRange((node.parent).typeParameters, start, end) || + getListIfStartEndIsInListRange((node.parent).parameters, start, end); } case SyntaxKind.ClassDeclaration: - return getListIfStartEndIsInListRange((node.parent).typeParameters, node.getStart(sourceFile), node.getEnd()); + return getListIfStartEndIsInListRange((node.parent).typeParameters, node.getStart(sourceFile), end); case SyntaxKind.NewExpression: case SyntaxKind.CallExpression: { const start = node.getStart(sourceFile); - return getListIfStartEndIsInListRange((node.parent).typeArguments, start, node.getEnd()) || - getListIfStartEndIsInListRange((node.parent).arguments, start, node.getEnd()); + return getListIfStartEndIsInListRange((node.parent).typeArguments, start, end) || + getListIfStartEndIsInListRange((node.parent).arguments, start, end); } case SyntaxKind.VariableDeclarationList: - return getListIfStartEndIsInListRange((node.parent).declarations, node.getStart(sourceFile), node.getEnd()); + return getListIfStartEndIsInListRange((node.parent).declarations, node.getStart(sourceFile), end); case SyntaxKind.NamedImports: case SyntaxKind.NamedExports: - return getListIfStartEndIsInListRange((node.parent).elements, node.getStart(sourceFile), node.getEnd()); + return getListIfStartEndIsInListRange((node.parent).elements, node.getStart(sourceFile), end); + case SyntaxKind.ObjectBindingPattern: + case SyntaxKind.ArrayBindingPattern: + return getListIfStartEndIsInListRange((node.parent).elements, node.getStart(sourceFile), end); } } return undefined; diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts new file mode 100644 index 0000000000000..13c2183618e52 --- /dev/null +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts @@ -0,0 +1,26 @@ +/// + +// @noUnusedLocals: true + +////{ +//// const { x, y } = o; +//// x; +////} +////{ +//// const { x, y } = o; +//// y; +////} + +verify.codeFixAll({ + fixId: "unusedIdentifier_delete", + fixAllDescription: "Delete all unused declarations", + newFileContent: +`{ + const { x } = o; + x; +} +{ + const { y } = o; + y; +}`, +}); From 2b47e154f398edda77d710e50bd6e50729fbadf4 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 8 May 2018 09:58:13 -0700 Subject: [PATCH 2/2] Add array destructure tests --- src/services/codefixes/fixUnusedIdentifier.ts | 15 +++++- ...usedIdentifier_destructure_partlyUnused.ts | 49 +++++++++++++++++++ 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index 8a160fbfb60e0..9cb1f457862b7 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -171,9 +171,20 @@ namespace ts.codefix { } break; - case SyntaxKind.BindingElement: - changes.deleteNodeInList(sourceFile, parent); + case SyntaxKind.BindingElement: { + const pattern = (parent as BindingElement).parent; + switch (pattern.kind) { + case SyntaxKind.ArrayBindingPattern: + changes.deleteNode(sourceFile, parent); // Don't delete ',' + break; + case SyntaxKind.ObjectBindingPattern: + changes.deleteNodeInList(sourceFile, parent); + break; + default: + return Debug.assertNever(pattern); + } break; + } // handle case where 'import a = A;' case SyntaxKind.ImportEqualsDeclaration: diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts index 13c2183618e52..6ed5973d400f0 100644 --- a/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts @@ -10,6 +10,31 @@ //// const { x, y } = o; //// y; ////} +////{ +//// const { x, y, z } = o; +//// y; +////} +////{ +//// const { x, y, z } = o; +//// x; z; +////} +////{ +//// const [x, y] = o; +//// x; +////} +////{ +//// const [x, y] = o; +//// y; +////} +////{ +//// const [x, y, z] = o; +//// y; +////} +////{ +//// const [x, y, z] = o; +//// x; z; +////} + verify.codeFixAll({ fixId: "unusedIdentifier_delete", @@ -22,5 +47,29 @@ verify.codeFixAll({ { const { y } = o; y; +} +{ + const { y } = o; + y; +} +{ + const { x, z } = o; + x; z; +} +{ + const [x,] = o; + x; +} +{ + const [, y] = o; + y; +} +{ + const [, y,] = o; + y; +} +{ + const [x,, z] = o; + x; z; }`, });