diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts
index 59f22c8a9fbe0..23f15afe8f8ef 100644
--- a/src/services/textChanges.ts
+++ b/src/services/textChanges.ts
@@ -993,6 +993,27 @@ namespace ts.textChanges {
return skipTrivia(sourceFile.text, getAdjustedStartPosition(sourceFile, node, { leadingTriviaOption: LeadingTriviaOption.IncludeAll }), /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
}
+ function endPositionToDeleteNodeInList(sourceFile: SourceFile, node: Node, prevNode: Node | undefined, nextNode: Node): number {
+ const end = startPositionToDeleteNodeInList(sourceFile, nextNode);
+ if (prevNode === undefined || positionsAreOnSameLine(getAdjustedEndPosition(sourceFile, node, {}), end, sourceFile)) {
+ return end;
+ }
+ const token = findPrecedingToken(nextNode.getStart(sourceFile), sourceFile);
+ if (isSeparator(node, token)) {
+ const prevToken = findPrecedingToken(node.getStart(sourceFile), sourceFile);
+ if (isSeparator(prevNode, prevToken)) {
+ const pos = skipTrivia(sourceFile.text, token.getEnd(), /*stopAfterLineBreak*/ true, /*stopAtComments*/ true);
+ if (positionsAreOnSameLine(prevToken.getStart(sourceFile), token.getStart(sourceFile), sourceFile)) {
+ return isLineBreak(sourceFile.text.charCodeAt(pos - 1)) ? pos - 1 : pos;
+ }
+ if (isLineBreak(sourceFile.text.charCodeAt(pos))) {
+ return pos;
+ }
+ }
+ }
+ return end;
+ }
+
function getClassOrObjectBraceEnds(cls: ClassLikeDeclaration | InterfaceDeclaration | ObjectLiteralExpression, sourceFile: SourceFile): [number | undefined, number | undefined] {
const open = findChildOfKind(cls, SyntaxKind.OpenBraceToken, sourceFile);
const close = findChildOfKind(cls, SyntaxKind.CloseBraceToken, sourceFile);
@@ -1589,9 +1610,10 @@ namespace ts.textChanges {
// That's handled in the end by `finishTrailingCommaAfterDeletingNodesInList`.
Debug.assert(!deletedNodesInLists.has(node), "Deleting a node twice");
deletedNodesInLists.add(node);
+
changes.deleteRange(sourceFile, {
pos: startPositionToDeleteNodeInList(sourceFile, node),
- end: index === containingList.length - 1 ? getAdjustedEndPosition(sourceFile, node, {}) : startPositionToDeleteNodeInList(sourceFile, containingList[index + 1]),
+ end: index === containingList.length - 1 ? getAdjustedEndPosition(sourceFile, node, {}) : endPositionToDeleteNodeInList(sourceFile, node, containingList[index - 1], containingList[index + 1]),
});
}
}
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements1.ts
similarity index 100%
rename from tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements.ts
rename to tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements1.ts
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements2.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements2.ts
new file mode 100644
index 0000000000000..e04ea447ffbcb
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements2.ts
@@ -0,0 +1,22 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f({
+//// a, b,
+//// c,
+////}: any)|] {
+//// a;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`function f({
+ a,
+ c,
+}: any)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements3.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements3.ts
new file mode 100644
index 0000000000000..99260954eb81d
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements3.ts
@@ -0,0 +1,26 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f({
+//// a, b,
+////
+////
+//// c,
+////}: any)|] {
+//// a;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`function f({
+ a,
+
+
+ c,
+}: any)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements4.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements4.ts
new file mode 100644
index 0000000000000..5f6ea4ee6fb46
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements4.ts
@@ -0,0 +1,22 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f({
+//// a, b, /* comment related to c */
+//// c,
+////}: any)|] {
+//// a;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`function f({
+ a, /* comment related to c */
+ c,
+}: any)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements5.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements5.ts
new file mode 100644
index 0000000000000..cf7adbb5eba81
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements5.ts
@@ -0,0 +1,23 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f({
+//// a,
+//// b,
+//// c,
+////}: any)|] {
+//// b;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'a'",
+ newRangeContent:
+`function f({
+ b,
+ c,
+}: any)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements6.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements6.ts
new file mode 100644
index 0000000000000..a3c7023f953dc
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_destructuring_elements6.ts
@@ -0,0 +1,25 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f({
+//// a,
+//// b,
+////
+//// c,
+////}: any)|] {
+//// a;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`function f({
+ a,
+
+ c,
+}: any)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier1.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier1.ts
new file mode 100644
index 0000000000000..af365fdd993cb
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier1.ts
@@ -0,0 +1,23 @@
+///
+
+// @noUnusedLocals: true
+////[|import {
+//// a, b, c, d,
+//// e, f,
+////} from "fs";|]
+////
+////a;
+////b;
+////c;
+////e;
+////f;
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'd'",
+ newRangeContent:
+`import {
+ a, b, c,
+ e, f,
+} from "fs";`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier2.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier2.ts
new file mode 100644
index 0000000000000..bcb9c40dd7a92
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier2.ts
@@ -0,0 +1,31 @@
+///
+
+// @noUnusedLocals: true
+////[|import {
+//// a, b, c, d,
+////
+////
+////
+////
+//// e, f,
+////} from "fs";|]
+////
+////a;
+////b;
+////c;
+////e;
+////f;
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'd'",
+ newRangeContent:
+`import {
+ a, b, c,
+
+
+
+
+ e, f,
+} from "fs";`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier3.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier3.ts
new file mode 100644
index 0000000000000..0fb9a2fe99643
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier3.ts
@@ -0,0 +1,23 @@
+///
+
+// @noUnusedLocals: true
+////[|import {
+//// a, b, c, d, /** comment related to e */
+//// e, f,
+////} from "fs";|]
+////
+////a;
+////b;
+////c;
+////e;
+////f;
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'd'",
+ newRangeContent:
+`import {
+ a, b, c, /** comment related to e */
+ e, f,
+} from "fs";`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier4.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier4.ts
new file mode 100644
index 0000000000000..925a016d90d2e
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier4.ts
@@ -0,0 +1,21 @@
+///
+
+// @noUnusedLocals: true
+////[|import {
+//// a,
+//// b,
+//// c,
+////} from "fs";|]
+////
+////a;
+////c;
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`import {
+ a,
+ c,
+} from "fs";`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier5.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier5.ts
new file mode 100644
index 0000000000000..75c9c73eb3ee8
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_importSpecifier5.ts
@@ -0,0 +1,25 @@
+///
+
+// @noUnusedLocals: true
+////[|import {
+//// a,
+//// b,
+////
+////
+//// c,
+////} from "fs";|]
+////
+////a;
+////c;
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`import {
+ a,
+
+
+ c,
+} from "fs";`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter1.ts
similarity index 100%
rename from tests/cases/fourslash/codeFixUnusedIdentifier_parameter.ts
rename to tests/cases/fourslash/codeFixUnusedIdentifier_parameter1.ts
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter2.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter2.ts
new file mode 100644
index 0000000000000..84af6f69bb62e
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter2.ts
@@ -0,0 +1,22 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f(
+//// a: number, b: number,
+//// c: number,
+////)|] {
+//// a;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`function f(
+ a: number,
+ c: number,
+)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter3.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter3.ts
new file mode 100644
index 0000000000000..a4078ccc6a54a
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter3.ts
@@ -0,0 +1,26 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f(
+//// a: number, b: number,
+////
+//// // comment
+//// c: number,
+////)|] {
+//// a;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`function f(
+ a: number,
+
+ // comment
+ c: number,
+)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter4.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter4.ts
new file mode 100644
index 0000000000000..12514358f2ab1
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter4.ts
@@ -0,0 +1,22 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f(
+//// a: number, b: number, /* comment related to c */
+//// c: number,
+////)|] {
+//// a;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`function f(
+ a: number, /* comment related to c */
+ c: number,
+)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter5.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter5.ts
new file mode 100644
index 0000000000000..25b513dcc0dee
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter5.ts
@@ -0,0 +1,23 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f(
+//// a: number,
+//// b: number,
+//// c: number,
+////)|] {
+//// b;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'a'",
+ newRangeContent:
+`function f(
+ b: number,
+ c: number,
+)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_parameter6.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter6.ts
new file mode 100644
index 0000000000000..c676935936bad
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_parameter6.ts
@@ -0,0 +1,27 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////[|function f(
+//// a: number,
+//// b: number,
+////
+////
+//// c: number,
+////)|] {
+//// a;
+//// c;
+////}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'b'",
+ newRangeContent:
+`function f(
+ a: number,
+
+
+ c: number,
+)`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter1.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter1.ts
new file mode 100644
index 0000000000000..4ea7dad3a4ac3
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter1.ts
@@ -0,0 +1,19 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////function f<
+//// T1, T2,
+//// T3,
+////>(a: T1, b: T3) {}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'T2'",
+ newFileContent:
+`function f<
+ T1,
+ T3,
+>(a: T1, b: T3) {}`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter2.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter2.ts
new file mode 100644
index 0000000000000..4bacbca4a9248
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter2.ts
@@ -0,0 +1,23 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////function f<
+//// T1, T2,
+////
+////
+//// T3,
+////>(a: T1, b: T3) {}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'T2'",
+ newFileContent:
+`function f<
+ T1,
+
+
+ T3,
+>(a: T1, b: T3) {}`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter3.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter3.ts
new file mode 100644
index 0000000000000..f2349a3630591
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter3.ts
@@ -0,0 +1,19 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////function f<
+//// T1, T2, /** comment related to T3 */
+//// T3,
+////>(a: T1, b: T3) {}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'T2'",
+ newFileContent:
+`function f<
+ T1, /** comment related to T3 */
+ T3,
+>(a: T1, b: T3) {}`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter4.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter4.ts
new file mode 100644
index 0000000000000..79e0e5fc78c35
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter4.ts
@@ -0,0 +1,20 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////function f<
+//// T1,
+//// T2,
+//// T3,
+////>(a: T1, b: T3) {}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'T2'",
+ newFileContent:
+`function f<
+ T1,
+ T3,
+>(a: T1, b: T3) {}`
+});
diff --git a/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter5.ts b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter5.ts
new file mode 100644
index 0000000000000..0bdbf1bccdb22
--- /dev/null
+++ b/tests/cases/fourslash/codeFixUnusedIdentifier_typeParameter5.ts
@@ -0,0 +1,24 @@
+///
+
+// @noUnusedLocals: true
+// @noUnusedParameters: true
+
+////function f<
+//// T1,
+//// T2,
+////
+////
+//// T3,
+////>(a: T1, b: T3) {}
+
+verify.codeFix({
+ index: 0,
+ description: "Remove unused declaration for: 'T2'",
+ newFileContent:
+`function f<
+ T1,
+
+
+ T3,
+>(a: T1, b: T3) {}`
+});