diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index fd360c73ea1ad..9cb1f457862b7 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -171,6 +171,21 @@ namespace ts.codefix { } break; + 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: 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..6ed5973d400f0 --- /dev/null +++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructure_partlyUnused.ts @@ -0,0 +1,75 @@ +/// + +// @noUnusedLocals: true + +////{ +//// const { x, y } = o; +//// x; +////} +////{ +//// 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", + fixAllDescription: "Delete all unused declarations", + newFileContent: +`{ + const { x } = o; + x; +} +{ + 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; +}`, +});