From 05ec512d32bae646d96cba97595a173a11a02b88 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Tue, 11 Oct 2016 15:04:04 -0700 Subject: [PATCH 01/11] Codefixes for unused variables, properties etc. --- src/harness/fourslash.ts | 2 +- src/services/codefixes/fixes.ts | 1 + .../codefixes/unusedIdentifierFixes.ts | 153 ++++++++++++++++++ .../fourslash/unusedClassInNamespace1.ts | 10 ++ .../fourslash/unusedClassInNamespace2.ts | 15 ++ .../fourslash/unusedClassInNamespace3.ts | 12 ++ .../fourslash/unusedClassInNamespace4.ts | 19 +++ .../fourslash/unusedClassInNamespace5.ts | 26 +++ .../fourslash/unusedClassInNamespace6.ts | 27 ++++ .../fourslash/unusedConstantInFunction1.ts | 10 ++ .../cases/fourslash/unusedEnumInFunction1.ts | 11 ++ .../fourslash/unusedFunctionInNamespace1.ts | 10 ++ .../fourslash/unusedFunctionInNamespace2.ts | 14 ++ .../fourslash/unusedFunctionInNamespace3.ts | 12 ++ .../fourslash/unusedFunctionInNamespace4.ts | 11 ++ .../fourslash/unusedFunctionInNamespace5.ts | 28 ++++ tests/cases/fourslash/unusedImports10FS.ts | 16 ++ tests/cases/fourslash/unusedImports1FS.ts | 12 ++ tests/cases/fourslash/unusedImports2FS.ts | 20 +++ tests/cases/fourslash/unusedImports3FS.ts | 24 +++ tests/cases/fourslash/unusedImports4FS.ts | 24 +++ tests/cases/fourslash/unusedImports5FS.ts | 24 +++ tests/cases/fourslash/unusedImports6FS.ts | 20 +++ tests/cases/fourslash/unusedImports7FS.ts | 20 +++ tests/cases/fourslash/unusedImports8FS.ts | 24 +++ tests/cases/fourslash/unusedImports9FS.ts | 20 +++ .../fourslash/unusedInterfaceInNamespace1.ts | 11 ++ .../fourslash/unusedInterfaceInNamespace2.ts | 12 ++ .../fourslash/unusedLocalsInFunction1.ts | 10 ++ .../fourslash/unusedLocalsInFunction2.ts | 9 ++ .../fourslash/unusedLocalsInFunction3.ts | 10 ++ .../fourslash/unusedLocalsInFunction4.ts | 10 ++ .../fourslash/unusedLocalsInMethodFS1.ts | 12 ++ .../fourslash/unusedLocalsInMethodFS2.ts | 12 ++ .../fourslash/unusedLocalsinConstructorFS1.ts | 12 ++ .../fourslash/unusedLocalsinConstructorFS2.ts | 18 +++ tests/cases/fourslash/unusedMethodInClass1.ts | 11 ++ tests/cases/fourslash/unusedMethodInClass2.ts | 15 ++ tests/cases/fourslash/unusedMethodInClass3.ts | 11 ++ tests/cases/fourslash/unusedMethodInClass4.ts | 12 ++ .../fourslash/unusedNamespaceInNamespace.ts | 13 ++ .../unusedParameterInConstructor1.ts | 8 + .../fourslash/unusedParameterInFunction1.ts | 7 + .../fourslash/unusedParameterInFunction2.ts | 8 + .../fourslash/unusedParameterInFunction3.ts | 8 + .../fourslash/unusedParameterInFunction4.ts | 9 ++ .../fourslash/unusedParameterInLambda1.ts | 9 ++ .../fourslash/unusedTypeParametersInClass1.ts | 7 + .../fourslash/unusedTypeParametersInClass2.ts | 8 + .../fourslash/unusedTypeParametersInClass3.ts | 9 ++ .../unusedTypeParametersInFunction1.ts | 6 + .../unusedTypeParametersInFunction2.ts | 6 + .../unusedTypeParametersInFunction3.ts | 6 + .../unusedTypeParametersInInterface1.ts | 7 + .../unusedTypeParametersInLambda1.ts | 9 ++ .../unusedTypeParametersInLambda2.ts | 9 ++ .../unusedTypeParametersInLambda3.ts | 10 ++ .../unusedTypeParametersInLambda4.ts | 9 ++ .../unusedTypeParametersInMethod1.ts | 8 + .../unusedTypeParametersInMethod2.ts | 8 + .../unusedTypeParametersInMethods1.ts | 8 + .../cases/fourslash/unusedVariableInBlocks.ts | 15 ++ .../cases/fourslash/unusedVariableInClass1.ts | 8 + .../cases/fourslash/unusedVariableInClass2.ts | 9 ++ .../cases/fourslash/unusedVariableInClass3.ts | 8 + .../fourslash/unusedVariableInForLoop1FS.ts | 11 ++ .../fourslash/unusedVariableInForLoop2FS.ts | 10 ++ .../fourslash/unusedVariableInForLoop3FS.ts | 10 ++ .../fourslash/unusedVariableInForLoop4FS.ts | 10 ++ .../fourslash/unusedVariableInForLoop5FS.ts | 11 ++ .../fourslash/unusedVariableInForLoop6FS.ts | 11 ++ .../fourslash/unusedVariableInForLoop7FS.ts | 12 ++ .../fourslash/unusedVariableInModule1.ts | 9 ++ .../fourslash/unusedVariableInModule2.ts | 10 ++ .../fourslash/unusedVariableInModule3.ts | 9 ++ .../fourslash/unusedVariableInModule4.ts | 10 ++ .../fourslash/unusedVariableInNamespace1.ts | 8 + .../fourslash/unusedVariableInNamespace2.ts | 12 ++ .../fourslash/unusedVariableInNamespace3.ts | 12 ++ 79 files changed, 1086 insertions(+), 1 deletion(-) create mode 100644 src/services/codefixes/unusedIdentifierFixes.ts create mode 100644 tests/cases/fourslash/unusedClassInNamespace1.ts create mode 100644 tests/cases/fourslash/unusedClassInNamespace2.ts create mode 100644 tests/cases/fourslash/unusedClassInNamespace3.ts create mode 100644 tests/cases/fourslash/unusedClassInNamespace4.ts create mode 100644 tests/cases/fourslash/unusedClassInNamespace5.ts create mode 100644 tests/cases/fourslash/unusedClassInNamespace6.ts create mode 100644 tests/cases/fourslash/unusedConstantInFunction1.ts create mode 100644 tests/cases/fourslash/unusedEnumInFunction1.ts create mode 100644 tests/cases/fourslash/unusedFunctionInNamespace1.ts create mode 100644 tests/cases/fourslash/unusedFunctionInNamespace2.ts create mode 100644 tests/cases/fourslash/unusedFunctionInNamespace3.ts create mode 100644 tests/cases/fourslash/unusedFunctionInNamespace4.ts create mode 100644 tests/cases/fourslash/unusedFunctionInNamespace5.ts create mode 100644 tests/cases/fourslash/unusedImports10FS.ts create mode 100644 tests/cases/fourslash/unusedImports1FS.ts create mode 100644 tests/cases/fourslash/unusedImports2FS.ts create mode 100644 tests/cases/fourslash/unusedImports3FS.ts create mode 100644 tests/cases/fourslash/unusedImports4FS.ts create mode 100644 tests/cases/fourslash/unusedImports5FS.ts create mode 100644 tests/cases/fourslash/unusedImports6FS.ts create mode 100644 tests/cases/fourslash/unusedImports7FS.ts create mode 100644 tests/cases/fourslash/unusedImports8FS.ts create mode 100644 tests/cases/fourslash/unusedImports9FS.ts create mode 100644 tests/cases/fourslash/unusedInterfaceInNamespace1.ts create mode 100644 tests/cases/fourslash/unusedInterfaceInNamespace2.ts create mode 100644 tests/cases/fourslash/unusedLocalsInFunction1.ts create mode 100644 tests/cases/fourslash/unusedLocalsInFunction2.ts create mode 100644 tests/cases/fourslash/unusedLocalsInFunction3.ts create mode 100644 tests/cases/fourslash/unusedLocalsInFunction4.ts create mode 100644 tests/cases/fourslash/unusedLocalsInMethodFS1.ts create mode 100644 tests/cases/fourslash/unusedLocalsInMethodFS2.ts create mode 100644 tests/cases/fourslash/unusedLocalsinConstructorFS1.ts create mode 100644 tests/cases/fourslash/unusedLocalsinConstructorFS2.ts create mode 100644 tests/cases/fourslash/unusedMethodInClass1.ts create mode 100644 tests/cases/fourslash/unusedMethodInClass2.ts create mode 100644 tests/cases/fourslash/unusedMethodInClass3.ts create mode 100644 tests/cases/fourslash/unusedMethodInClass4.ts create mode 100644 tests/cases/fourslash/unusedNamespaceInNamespace.ts create mode 100644 tests/cases/fourslash/unusedParameterInConstructor1.ts create mode 100644 tests/cases/fourslash/unusedParameterInFunction1.ts create mode 100644 tests/cases/fourslash/unusedParameterInFunction2.ts create mode 100644 tests/cases/fourslash/unusedParameterInFunction3.ts create mode 100644 tests/cases/fourslash/unusedParameterInFunction4.ts create mode 100644 tests/cases/fourslash/unusedParameterInLambda1.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInClass1.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInClass2.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInClass3.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInFunction1.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInFunction2.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInFunction3.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInInterface1.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInLambda1.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInLambda2.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInLambda3.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInLambda4.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInMethod1.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInMethod2.ts create mode 100644 tests/cases/fourslash/unusedTypeParametersInMethods1.ts create mode 100644 tests/cases/fourslash/unusedVariableInBlocks.ts create mode 100644 tests/cases/fourslash/unusedVariableInClass1.ts create mode 100644 tests/cases/fourslash/unusedVariableInClass2.ts create mode 100644 tests/cases/fourslash/unusedVariableInClass3.ts create mode 100644 tests/cases/fourslash/unusedVariableInForLoop1FS.ts create mode 100644 tests/cases/fourslash/unusedVariableInForLoop2FS.ts create mode 100644 tests/cases/fourslash/unusedVariableInForLoop3FS.ts create mode 100644 tests/cases/fourslash/unusedVariableInForLoop4FS.ts create mode 100644 tests/cases/fourslash/unusedVariableInForLoop5FS.ts create mode 100644 tests/cases/fourslash/unusedVariableInForLoop6FS.ts create mode 100644 tests/cases/fourslash/unusedVariableInForLoop7FS.ts create mode 100644 tests/cases/fourslash/unusedVariableInModule1.ts create mode 100644 tests/cases/fourslash/unusedVariableInModule2.ts create mode 100644 tests/cases/fourslash/unusedVariableInModule3.ts create mode 100644 tests/cases/fourslash/unusedVariableInModule4.ts create mode 100644 tests/cases/fourslash/unusedVariableInNamespace1.ts create mode 100644 tests/cases/fourslash/unusedVariableInNamespace2.ts create mode 100644 tests/cases/fourslash/unusedVariableInNamespace3.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index f54804c0eb5d4..e58a189c923fc 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2049,7 +2049,7 @@ namespace FourSlash { this.raiseError("Errors expected."); } - if (diagnostics.length > 1 && errorCode !== undefined) { + if (diagnostics.length > 1 && errorCode === undefined) { this.raiseError("When there's more than one error, you must specify the errror to fix."); } diff --git a/src/services/codefixes/fixes.ts b/src/services/codefixes/fixes.ts index d64a99ca1b9e6..ae13a9658387c 100644 --- a/src/services/codefixes/fixes.ts +++ b/src/services/codefixes/fixes.ts @@ -1 +1,2 @@ /// +/// \ No newline at end of file diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts new file mode 100644 index 0000000000000..9a69af04bfc83 --- /dev/null +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -0,0 +1,153 @@ +/* @internal */ +namespace ts.codefix { + registerCodeFix({ + errorCodes: [ + Diagnostics._0_is_declared_but_never_used.code, + Diagnostics.Property_0_is_declared_but_never_used.code + ], + getCodeActions: (context: CodeFixContext) => { + const sourceFile = context.sourceFile; + const start = context.span.start; + const token = getTokenAtPosition(sourceFile, start); + + if (token.kind === ts.SyntaxKind.Identifier) { + if (token.parent.kind === ts.SyntaxKind.VariableDeclaration) { + if (token.parent.parent.parent.kind === SyntaxKind.ForStatement) { + const forStatement = token.parent.parent.parent; + const initializer = forStatement.initializer; + if (initializer.declarations.length === 1) { + return createCodeFix("", initializer.pos, initializer.end - initializer.pos); + } + else { + if (initializer.declarations[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + else if (token.parent.parent.parent.kind === SyntaxKind.ForInStatement) { + const forInStatement = token.parent.parent.parent; + const initializer = forInStatement.initializer; + return createCodeFix("{}", initializer.declarations[0].pos, initializer.declarations[0].end - initializer.declarations[0].pos); + } + else if (token.parent.parent.parent.kind === SyntaxKind.ForOfStatement) { + const forOfStatement = token.parent.parent.parent; + const initializer = forOfStatement.initializer; + return createCodeFix("{}", initializer.declarations[0].pos, initializer.declarations[0].end - initializer.declarations[0].pos); + } + else if (token.parent.parent.kind === SyntaxKind.CatchClause) { + const catchClause = token.parent.parent; + const parameter = catchClause.variableDeclaration.getChildren()[0]; + return createCodeFix("", parameter.pos, parameter.end - parameter.pos); + } + else { + const variableStatement = token.parent.parent.parent; + if (variableStatement.declarationList.declarations.length === 1) { + return createCodeFix("", variableStatement.pos, variableStatement.end - variableStatement.pos); + } + else { + const declarations = variableStatement.declarationList.declarations; + if (declarations[0].name === token) { + return createCodeFix("", token.parent.pos + 1, token.parent.end - token.parent.pos); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + } + + if (token.parent.kind === SyntaxKind.FunctionDeclaration || + token.parent.kind === SyntaxKind.ClassDeclaration || + token.parent.kind === SyntaxKind.InterfaceDeclaration || + token.parent.kind === SyntaxKind.MethodDeclaration || + token.parent.kind === SyntaxKind.ModuleDeclaration || + token.parent.kind === SyntaxKind.PropertyDeclaration || + token.parent.kind === SyntaxKind.ArrowFunction) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + + if (token.parent.kind === SyntaxKind.TypeParameter) { + const typeParameters = (token.parent.parent).typeParameters; + if (typeParameters.length === 1) { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 2); + } + else { + if (typeParameters[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + + if (token.parent.kind === ts.SyntaxKind.Parameter) { + const functionDeclaration = token.parent.parent; + if (functionDeclaration.parameters.length === 1) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + else { + if (functionDeclaration.parameters[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + + if (token.parent.kind === SyntaxKind.ImportSpecifier) { + const namedImports = token.parent.parent; + const elements = namedImports.elements; + if (elements.length === 1) { + // Only 1 import and it is unused. So the entire line could be removed. + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + else { + if (elements[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } + } + + if (token.parent.parent.kind === SyntaxKind.ImportClause || token.parent.parent.kind === SyntaxKind.ImportDeclaration) { + return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); + } + + if (token.parent.kind === SyntaxKind.ImportEqualsDeclaration) { + return createCodeFix("{}", token.pos, token.end - token.pos); + } + + if (token.parent.kind === SyntaxKind.EnumDeclaration) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + } + + if (token.kind === SyntaxKind.PrivateKeyword && token.parent.kind === SyntaxKind.PropertyDeclaration) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + + if (token.kind === SyntaxKind.AsteriskToken && token.parent.kind === SyntaxKind.NamespaceImport) { + return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); + } + + return undefined; + + function createCodeFix(newText: string, start: number, length: number): CodeAction[] { + return [{ + description: getLocaleSpecificMessage(Diagnostics.Remove_unused_identifiers), + changes: [{ + fileName: sourceFile.fileName, + textChanges: [{ newText, span: { start, length } }] + }] + }]; + } + } + }); +} diff --git a/tests/cases/fourslash/unusedClassInNamespace1.ts b/tests/cases/fourslash/unusedClassInNamespace1.ts new file mode 100644 index 0000000000000..586202ab0c7d4 --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace1.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// class class1 { +//// } +//// } |] + +verify.codeFixAtPosition(`namespace greeter { +}`); diff --git a/tests/cases/fourslash/unusedClassInNamespace2.ts b/tests/cases/fourslash/unusedClassInNamespace2.ts new file mode 100644 index 0000000000000..c182f4e3655dc --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace2.ts @@ -0,0 +1,15 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// export class class2 { +//// } +//// class class1 { +//// } +//// } |] + +verify.codeFixAtPosition(`namespace greeter { + export class class2 { + } +}`); + diff --git a/tests/cases/fourslash/unusedClassInNamespace3.ts b/tests/cases/fourslash/unusedClassInNamespace3.ts new file mode 100644 index 0000000000000..6102f744717d6 --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace3.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +//// [| namespace Validation { +//// class c1 { +//// +//// }/*1*/ +//// } |] + +verify.codeFixAtPosition(`namespace Validation { +}`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedClassInNamespace4.ts b/tests/cases/fourslash/unusedClassInNamespace4.ts new file mode 100644 index 0000000000000..79701a5e0e20f --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace4.ts @@ -0,0 +1,19 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true + +//// [| namespace Validation { +//// class c1 { +//// +//// } +//// +//// export class c2 { +//// +//// } +//// } |] + +verify.codeFixAtPosition(`namespace Validation { + export class c2 { + } +}`); diff --git a/tests/cases/fourslash/unusedClassInNamespace5.ts b/tests/cases/fourslash/unusedClassInNamespace5.ts new file mode 100644 index 0000000000000..80d8fe857bd12 --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace5.ts @@ -0,0 +1,26 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true + +//// [| namespace Validation { +//// class c1 { +//// +//// } +//// +//// export class c2 { +//// +//// } +//// +//// class c3 extends c1 { +//// +//// } +////} |] + +verify.codeFixAtPosition(`namespace Validation { + class c1 { + } + + export class c2 { + } +}`); diff --git a/tests/cases/fourslash/unusedClassInNamespace6.ts b/tests/cases/fourslash/unusedClassInNamespace6.ts new file mode 100644 index 0000000000000..5db5b1aefa65d --- /dev/null +++ b/tests/cases/fourslash/unusedClassInNamespace6.ts @@ -0,0 +1,27 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +//// [| namespace Validation { +//// class c1 { +//// +//// } +//// +//// export class c2 { +//// +//// } +//// +//// class c3 { +//// public x: c1; +//// } +////} |] + +verify.codeFixAtPosition(`namespace Validation { + class c1 { + + } + + export class c2 { + + } +}`); diff --git a/tests/cases/fourslash/unusedConstantInFunction1.ts b/tests/cases/fourslash/unusedConstantInFunction1.ts new file mode 100644 index 0000000000000..df37325780997 --- /dev/null +++ b/tests/cases/fourslash/unusedConstantInFunction1.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// [| function f1 () { +//// const x: string = "x"; +//// } |] + +verify.codeFixAtPosition(`function f1 () { +}`); + diff --git a/tests/cases/fourslash/unusedEnumInFunction1.ts b/tests/cases/fourslash/unusedEnumInFunction1.ts new file mode 100644 index 0000000000000..1d88f07ebf76b --- /dev/null +++ b/tests/cases/fourslash/unusedEnumInFunction1.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// [| function f1 () { +//// enum Directions { Up, Down} +//// } |] + +verify.codeFixAtPosition(`function f1 () { +} +`); + diff --git a/tests/cases/fourslash/unusedFunctionInNamespace1.ts b/tests/cases/fourslash/unusedFunctionInNamespace1.ts new file mode 100644 index 0000000000000..e0f6b2e18ac15 --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace1.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// function function1() { +//// }/*1*/ +//// } |] + +verify.codeFixAtPosition(`namespace greeter { +}`); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace2.ts b/tests/cases/fourslash/unusedFunctionInNamespace2.ts new file mode 100644 index 0000000000000..c823777048e2e --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace2.ts @@ -0,0 +1,14 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// export function function2() { +//// } +//// function function1() { +//// } +////} |] + +verify.codeFixAtPosition(`namespace greeter { + export function function2() { + } +}`); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace3.ts b/tests/cases/fourslash/unusedFunctionInNamespace3.ts new file mode 100644 index 0000000000000..144e9f325b444 --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace3.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true + +//// [| namespace Validation { +//// function function1() { +//// } +////} |] + +verify.codeFixAtPosition(`namespace Validation { +}`); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace4.ts b/tests/cases/fourslash/unusedFunctionInNamespace4.ts new file mode 100644 index 0000000000000..5b5995da9c745 --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace4.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +//// [| namespace Validation { +//// var function1 = function() { +//// } +////} |] + +verify.codeFixAtPosition(`namespace Validation { +}`); diff --git a/tests/cases/fourslash/unusedFunctionInNamespace5.ts b/tests/cases/fourslash/unusedFunctionInNamespace5.ts new file mode 100644 index 0000000000000..fa1eed2364a51 --- /dev/null +++ b/tests/cases/fourslash/unusedFunctionInNamespace5.ts @@ -0,0 +1,28 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +////namespace Validation { +//// var function1 = function() { +//// } +//// +//// export function function2() { +//// +//// } +//// +//// [| function function3() { +//// function1(); +//// } +//// +//// function function4() { +//// +//// } +//// +//// exp ort let a = function3; |] +////} + +verify.codeFixAtPosition(`function function3() { + function1(); + } + + export let a = function3;`, 6133); diff --git a/tests/cases/fourslash/unusedImports10FS.ts b/tests/cases/fourslash/unusedImports10FS.ts new file mode 100644 index 0000000000000..2eb923c9b8fbc --- /dev/null +++ b/tests/cases/fourslash/unusedImports10FS.ts @@ -0,0 +1,16 @@ +/// + +// @noUnusedLocals: true +//// module A { +//// export class Calculator { +//// public handelChar() { +//// } +//// } +//// } + +//// module B { +//// [|import a = A;|] +//// } + +verify.codeFixAtPosition(" import {} = A;"); + diff --git a/tests/cases/fourslash/unusedImports1FS.ts b/tests/cases/fourslash/unusedImports1FS.ts new file mode 100644 index 0000000000000..c3ae198d876dc --- /dev/null +++ b/tests/cases/fourslash/unusedImports1FS.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import {/*0*/Calculator/*1*/} from "./file1" |] + +// @Filename: file1.ts +//// export class Calculator { +//// +//// } + +verify.codeFixAtPosition(`import {} from "./file1"`); diff --git a/tests/cases/fourslash/unusedImports2FS.ts b/tests/cases/fourslash/unusedImports2FS.ts new file mode 100644 index 0000000000000..a7144d1eb4976 --- /dev/null +++ b/tests/cases/fourslash/unusedImports2FS.ts @@ -0,0 +1,20 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import {Calculator} from "./file1" +//// import {test} from "./file1" |] + +//// var x = new Calculator(); +//// x.handleChar(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() {} +//// } +//// export function test() { +//// +//// } + +verify.codeFixAtPosition(`import {Calculator} from "./file1" +import {} from "./file1"`); diff --git a/tests/cases/fourslash/unusedImports3FS.ts b/tests/cases/fourslash/unusedImports3FS.ts new file mode 100644 index 0000000000000..f030232dc1e5b --- /dev/null +++ b/tests/cases/fourslash/unusedImports3FS.ts @@ -0,0 +1,24 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +////[| import {/*0*/Calculator,/*1*/ test, test2} from "./file1" |] + +//// test(); +//// test2(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() {} +//// } + +//// export function test() { +//// +//// } + +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {test, test2} from "./file1"`); + diff --git a/tests/cases/fourslash/unusedImports4FS.ts b/tests/cases/fourslash/unusedImports4FS.ts new file mode 100644 index 0000000000000..ab37928eb0164 --- /dev/null +++ b/tests/cases/fourslash/unusedImports4FS.ts @@ -0,0 +1,24 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import {Calculator/*0*/, test/*1*/, test2} from "./file1" |] +//// +//// var x = new Calculator(); +//// x.handleChar(); +//// test2(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() {} +//// } +//// +//// export function test() { +//// +//// } +//// +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {Calculator, test2} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports5FS.ts b/tests/cases/fourslash/unusedImports5FS.ts new file mode 100644 index 0000000000000..1d68f6ae64383 --- /dev/null +++ b/tests/cases/fourslash/unusedImports5FS.ts @@ -0,0 +1,24 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import {Calculator, test, test2} from "./file1" |] +//// +//// var x = new Calculator(); +//// x.handleChar(); +//// test(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() {} +//// } +//// +//// export function test() { +//// +//// } +//// +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {Calculator, test} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports6FS.ts b/tests/cases/fourslash/unusedImports6FS.ts new file mode 100644 index 0000000000000..c8e1af9231389 --- /dev/null +++ b/tests/cases/fourslash/unusedImports6FS.ts @@ -0,0 +1,20 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import d from "./file1" |] + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() { } +//// } + +//// export function test() { +//// +//// } + +//// export default function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports7FS.ts b/tests/cases/fourslash/unusedImports7FS.ts new file mode 100644 index 0000000000000..6dc0886e8ffbe --- /dev/null +++ b/tests/cases/fourslash/unusedImports7FS.ts @@ -0,0 +1,20 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import * as n from "./file1" |] + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() { } +//// } +//// +//// export function test() { +//// +//// } +//// +//// export default function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports8FS.ts b/tests/cases/fourslash/unusedImports8FS.ts new file mode 100644 index 0000000000000..02564e359895d --- /dev/null +++ b/tests/cases/fourslash/unusedImports8FS.ts @@ -0,0 +1,24 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [|import {Calculator as calc, test as t1, test2 as t2} from "./file1"|] +//// +//// var x = new calc(); +//// x.handleChar(); +//// t1(); + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() { } +//// } + +//// export function test() { +//// +//// } + +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition(`import {Calculator as calc, test as t1} from "./file1"`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports9FS.ts b/tests/cases/fourslash/unusedImports9FS.ts new file mode 100644 index 0000000000000..2ba30c95bb718 --- /dev/null +++ b/tests/cases/fourslash/unusedImports9FS.ts @@ -0,0 +1,20 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [|import c = require('./file1')|] + +// @Filename: file1.ts +//// export class Calculator { +//// handleChar() { } +//// } +//// +//// export function test() { +//// +//// } +//// +//// export function test2() { +//// +//// } + +verify.codeFixAtPosition("import {} = require('./file1')"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedInterfaceInNamespace1.ts b/tests/cases/fourslash/unusedInterfaceInNamespace1.ts new file mode 100644 index 0000000000000..8d07a8c79121e --- /dev/null +++ b/tests/cases/fourslash/unusedInterfaceInNamespace1.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// interface interface1 { +//// } +////} |] + +verify.codeFixAtPosition(` +namespace greeter { +}`); diff --git a/tests/cases/fourslash/unusedInterfaceInNamespace2.ts b/tests/cases/fourslash/unusedInterfaceInNamespace2.ts new file mode 100644 index 0000000000000..baa46c65a0ce6 --- /dev/null +++ b/tests/cases/fourslash/unusedInterfaceInNamespace2.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +////namespace greeter { +//// [| export interface interface2 { +//// } +//// interface interface1 { +//// } |] +////} + +verify.codeFixAtPosition(`export interface interface2 { +}`); diff --git a/tests/cases/fourslash/unusedLocalsInFunction1.ts b/tests/cases/fourslash/unusedLocalsInFunction1.ts new file mode 100644 index 0000000000000..2edd7c176e7dd --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInFunction1.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// [| function greeter() { +//// var x = 0; +////} |] + +verify.codeFixAtPosition(` +function greeter() { +}`); diff --git a/tests/cases/fourslash/unusedLocalsInFunction2.ts b/tests/cases/fourslash/unusedLocalsInFunction2.ts new file mode 100644 index 0000000000000..8f84362397461 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInFunction2.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +////function greeter() { +//// [| var x, y = 0; |] +//// x++; +////} + +verify.codeFixAtPosition("var x;", 6133); diff --git a/tests/cases/fourslash/unusedLocalsInFunction3.ts b/tests/cases/fourslash/unusedLocalsInFunction3.ts new file mode 100644 index 0000000000000..3fc925413900b --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInFunction3.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +////function greeter() { +//// [| var x, y = 0,z = 1; |] +//// x++; +//// z++; +////} + +verify.codeFixAtPosition("var x,z = 1;", 6133); diff --git a/tests/cases/fourslash/unusedLocalsInFunction4.ts b/tests/cases/fourslash/unusedLocalsInFunction4.ts new file mode 100644 index 0000000000000..54d3223f23608 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInFunction4.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +////function greeter() { +//// [| var x,y = 0,z = 1; |] +//// y++; +//// z++; +////} + +verify.codeFixAtPosition("var y = 0,z = 1;"); diff --git a/tests/cases/fourslash/unusedLocalsInMethodFS1.ts b/tests/cases/fourslash/unusedLocalsInMethodFS1.ts new file mode 100644 index 0000000000000..43b782ce2661a --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInMethodFS1.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////class greeter { +//// public function1() { +//// [| var /*0*/x,/*1*/ y = 10; |] +//// y++; +//// } +////} + +verify.codeFixAtPosition("var y = 10;"); diff --git a/tests/cases/fourslash/unusedLocalsInMethodFS2.ts b/tests/cases/fourslash/unusedLocalsInMethodFS2.ts new file mode 100644 index 0000000000000..322cfad394007 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsInMethodFS2.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////class greeter { +//// public function1() { +//// [| var x, y; |] +//// y = 1; +//// } +////} + +verify.codeFixAtPosition("var y;"); diff --git a/tests/cases/fourslash/unusedLocalsinConstructorFS1.ts b/tests/cases/fourslash/unusedLocalsinConstructorFS1.ts new file mode 100644 index 0000000000000..412b599b780a9 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsinConstructorFS1.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters:true +////class greeter { +//// [| constructor() { +//// var unused = 20; +//// } |] +////} + +verify.codeFixAtPosition(`constructor() { +}`); diff --git a/tests/cases/fourslash/unusedLocalsinConstructorFS2.ts b/tests/cases/fourslash/unusedLocalsinConstructorFS2.ts new file mode 100644 index 0000000000000..eff9b7c8d54b5 --- /dev/null +++ b/tests/cases/fourslash/unusedLocalsinConstructorFS2.ts @@ -0,0 +1,18 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +////class greeter { +//// [|constructor() { +//// var unused = 20; +//// var used = "dummy"; +//// used = used + "second part"; +//// }|] +////} + +verify.codeFixAtPosition(` + constructor() { + var used = "dummy"; + used = used + "second part"; + } +`); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedMethodInClass1.ts b/tests/cases/fourslash/unusedMethodInClass1.ts new file mode 100644 index 0000000000000..7795a4d15303e --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass1.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +////[| class greeter { +//// private function1() { +//// } +////} |] + +verify.codeFixAtPosition(` +class greeter { +}`); diff --git a/tests/cases/fourslash/unusedMethodInClass2.ts b/tests/cases/fourslash/unusedMethodInClass2.ts new file mode 100644 index 0000000000000..24b6fe155efb5 --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass2.ts @@ -0,0 +1,15 @@ +/// + +// @noUnusedLocals: true +//// [| class greeter { +//// public function2() { +//// } +//// private function1() { +//// } +////} |] + +verify.codeFixAtPosition(` +class greeter { + public function2() { + } +}`); diff --git a/tests/cases/fourslash/unusedMethodInClass3.ts b/tests/cases/fourslash/unusedMethodInClass3.ts new file mode 100644 index 0000000000000..eab535fb5af66 --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass3.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +////[|class greeter { +//// private function1 = function() { +//// } +////} |] + +verify.codeFixAtPosition(` +class greeter { +}`); diff --git a/tests/cases/fourslash/unusedMethodInClass4.ts b/tests/cases/fourslash/unusedMethodInClass4.ts new file mode 100644 index 0000000000000..ee27ec331eb84 --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass4.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +////class greeter { +//// [|public function2(){ +//// } +//// private function1 = function() { +//// } |] +////} + +verify.codeFixAtPosition(`public function2(){ +}`); diff --git a/tests/cases/fourslash/unusedNamespaceInNamespace.ts b/tests/cases/fourslash/unusedNamespaceInNamespace.ts new file mode 100644 index 0000000000000..41fe162ef1564 --- /dev/null +++ b/tests/cases/fourslash/unusedNamespaceInNamespace.ts @@ -0,0 +1,13 @@ +/// + +// @noUnusedLocals: true +//// [|namespace A { +//// namespace B { +//// } +//// }|] + +verify.codeFixAtPosition(` +namespace A { +} +`); + diff --git a/tests/cases/fourslash/unusedParameterInConstructor1.ts b/tests/cases/fourslash/unusedParameterInConstructor1.ts new file mode 100644 index 0000000000000..f53c6d3e8bdde --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInConstructor1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|constructor(private p1: string, public p2: boolean, public p3: any, p5)|] { p5; } +//// } + +verify.codeFixAtPosition("constructor(public p2: boolean, public p3: any, p5)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInFunction1.ts b/tests/cases/fourslash/unusedParameterInFunction1.ts new file mode 100644 index 0000000000000..2243af9f5f553 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInFunction1.ts @@ -0,0 +1,7 @@ +/// + +// @noUnusedParameters: true +////function [|greeter( x)|] { +////} + +verify.codeFixAtPosition("greeter()"); diff --git a/tests/cases/fourslash/unusedParameterInFunction2.ts b/tests/cases/fourslash/unusedParameterInFunction2.ts new file mode 100644 index 0000000000000..493eafc572223 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInFunction2.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedParameters: true +////function [|greeter(x,y)|] { +//// x++; +////} + +verify.codeFixAtPosition("greeter(x)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInFunction3.ts b/tests/cases/fourslash/unusedParameterInFunction3.ts new file mode 100644 index 0000000000000..6d79ba071b450 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInFunction3.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedParameters: true +////function [|greeter(x,y)|] { +//// y++; +////} + +verify.codeFixAtPosition("greeter(y)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInFunction4.ts b/tests/cases/fourslash/unusedParameterInFunction4.ts new file mode 100644 index 0000000000000..b536543fb6d59 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInFunction4.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedParameters: true +////[|function greeter(x,y,z) |] { +//// x++; +//// z++; +////} + +verify.codeFixAtPosition("function greeter(x,z)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInLambda1.ts b/tests/cases/fourslash/unusedParameterInLambda1.ts new file mode 100644 index 0000000000000..c462b7425694d --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInLambda1.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// function f1() { +//// [|return (x:number) => {}|] +//// } + +verify.codeFixAtPosition("return () => {}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInClass1.ts b/tests/cases/fourslash/unusedTypeParametersInClass1.ts new file mode 100644 index 0000000000000..ab654a5150e73 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInClass1.ts @@ -0,0 +1,7 @@ +/// + +// @noUnusedLocals: true +////[|class greeter |] { +////} + +verify.codeFixAtPosition("class greeter"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInClass2.ts b/tests/cases/fourslash/unusedTypeParametersInClass2.ts new file mode 100644 index 0000000000000..8e860c10e049b --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInClass2.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +////[|class greeter |] { +//// public a: X; +////} + +verify.codeFixAtPosition("class greeter"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInClass3.ts b/tests/cases/fourslash/unusedTypeParametersInClass3.ts new file mode 100644 index 0000000000000..75ae98f53e0ed --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInClass3.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +////[|class greeter |] { +//// public a: X; +//// public b: Z; +////} + +verify.codeFixAtPosition("class greeter"); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction1.ts b/tests/cases/fourslash/unusedTypeParametersInFunction1.ts new file mode 100644 index 0000000000000..7177ed41c8445 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInFunction1.ts @@ -0,0 +1,6 @@ +/// + +// @noUnusedLocals: true +//// [|function f1() {}|] + +verify.codeFixAtPosition("function f1() {}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction2.ts b/tests/cases/fourslash/unusedTypeParametersInFunction2.ts new file mode 100644 index 0000000000000..344ae303c75df --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInFunction2.ts @@ -0,0 +1,6 @@ +/// + +// @noUnusedLocals: true +//// [|function f1(a: X) {a}|] + +verify.codeFixAtPosition("function f1(a: X) {a}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInFunction3.ts b/tests/cases/fourslash/unusedTypeParametersInFunction3.ts new file mode 100644 index 0000000000000..746b174db18d9 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInFunction3.ts @@ -0,0 +1,6 @@ +/// + +// @noUnusedLocals: true +//// [|function f1(a: X) {a;var b:Z;b}|] + +verify.codeFixAtPosition("function f1(a: X) {a;var b:Z;b}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInInterface1.ts b/tests/cases/fourslash/unusedTypeParametersInInterface1.ts new file mode 100644 index 0000000000000..70d8bc7800cd8 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInInterface1.ts @@ -0,0 +1,7 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// [|interface I {}|] + +verify.codeFixAtPosition("interface I {}"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda1.ts b/tests/cases/fourslash/unusedTypeParametersInLambda1.ts new file mode 100644 index 0000000000000..73d7067236850 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInLambda1.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// function f1() { +//// [|return (x:number) => {x}|] +//// } + +verify.codeFixAtPosition("return (x:number) => {x}"); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda2.ts b/tests/cases/fourslash/unusedTypeParametersInLambda2.ts new file mode 100644 index 0000000000000..77c802f5c44f3 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInLambda2.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// var x : { +//// [|new (a: T): void;|] +//// } + +verify.codeFixAtPosition("new (a: T): void;"); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda3.ts b/tests/cases/fourslash/unusedTypeParametersInLambda3.ts new file mode 100644 index 0000000000000..0ecb0338be2ce --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInLambda3.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// class A { public x: Dummy } +//// var x : { +//// [|new (a: T): A;|] +//// } + +verify.codeFixAtPosition("new (a: T): A;"); diff --git a/tests/cases/fourslash/unusedTypeParametersInLambda4.ts b/tests/cases/fourslash/unusedTypeParametersInLambda4.ts new file mode 100644 index 0000000000000..5a226fc9005ef --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInLambda4.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +//// class A { +//// public x: T; +//// } +//// [|var y: new (a:T)=>void;|] + +verify.codeFixAtPosition("var y: new (a:T)=>void;"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInMethod1.ts b/tests/cases/fourslash/unusedTypeParametersInMethod1.ts new file mode 100644 index 0000000000000..7a9f04147d617 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInMethod1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|f1()|] {} +//// } + +verify.codeFixAtPosition("f1()"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInMethod2.ts b/tests/cases/fourslash/unusedTypeParametersInMethod2.ts new file mode 100644 index 0000000000000..3650cfbad98a0 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInMethod2.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|f1(a: U)|] {a;} +//// } + +verify.codeFixAtPosition("f1(a: U)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedTypeParametersInMethods1.ts b/tests/cases/fourslash/unusedTypeParametersInMethods1.ts new file mode 100644 index 0000000000000..cb9b965ca4d45 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeParametersInMethods1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class A { +//// [|public f1(a: X)|] { a; var b: Z; b } +//// } + +verify.codeFixAtPosition("public f1(a: X)"); diff --git a/tests/cases/fourslash/unusedVariableInBlocks.ts b/tests/cases/fourslash/unusedVariableInBlocks.ts new file mode 100644 index 0000000000000..e9dedaef31eb0 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInBlocks.ts @@ -0,0 +1,15 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|let x = 10; +//// { +//// let x = 11; +//// } +//// x;|] +//// } + +verify.codeFixAtPosition(`let x = 10; + { + } + x;`); diff --git a/tests/cases/fourslash/unusedVariableInClass1.ts b/tests/cases/fourslash/unusedVariableInClass1.ts new file mode 100644 index 0000000000000..82bb99016efd5 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInClass1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +////class greeter { +//// [|private greeting: string;|] +////} + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInClass2.ts b/tests/cases/fourslash/unusedVariableInClass2.ts new file mode 100644 index 0000000000000..c971092584a53 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInClass2.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +////class greeter { +//// [|public greeting1; +//// private greeting: string;|] +////} + +verify.codeFixAtPosition("public greeting1;"); diff --git a/tests/cases/fourslash/unusedVariableInClass3.ts b/tests/cases/fourslash/unusedVariableInClass3.ts new file mode 100644 index 0000000000000..8d2a62e7175b9 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInClass3.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +////class greeter {[| +//// private X = function() {}; +////|]} + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInForLoop1FS.ts b/tests/cases/fourslash/unusedVariableInForLoop1FS.ts new file mode 100644 index 0000000000000..0ee02ab43632d --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop1FS.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|for(var i = 0; ;) |]{ +//// +//// } +//// } + +verify.codeFixAtPosition("for(; ;)"); + diff --git a/tests/cases/fourslash/unusedVariableInForLoop2FS.ts b/tests/cases/fourslash/unusedVariableInForLoop2FS.ts new file mode 100644 index 0000000000000..1b1a0798c0445 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop2FS.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|for(var i = 0, j= 0; ;i++)|] { +//// +//// } +//// } + +verify.codeFixAtPosition("for(var i = 0; ;i++)"); diff --git a/tests/cases/fourslash/unusedVariableInForLoop3FS.ts b/tests/cases/fourslash/unusedVariableInForLoop3FS.ts new file mode 100644 index 0000000000000..4eed9599b1513 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop3FS.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|for(var i = 0, j= 0, k=0; ;i++, k++)|] { +//// +//// } +//// } + +verify.codeFixAtPosition("for(var i = 0, k=0; ;i++,k++)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedVariableInForLoop4FS.ts b/tests/cases/fourslash/unusedVariableInForLoop4FS.ts new file mode 100644 index 0000000000000..76e551612ba79 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop4FS.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// [|for(var i = 0, j= 0, k=0; ;j++, k++) |]{ +//// +//// } +//// } + +verify.codeFixAtPosition("for(var j = 0, k=0; ;j++,k++)"); diff --git a/tests/cases/fourslash/unusedVariableInForLoop5FS.ts b/tests/cases/fourslash/unusedVariableInForLoop5FS.ts new file mode 100644 index 0000000000000..60369da522d17 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop5FS.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// for ([|const elem in|] ["a", "b", "c"]) { +//// +//// } +//// } + +verify.codeFixAtPosition("const {} in "); + diff --git a/tests/cases/fourslash/unusedVariableInForLoop6FS.ts b/tests/cases/fourslash/unusedVariableInForLoop6FS.ts new file mode 100644 index 0000000000000..4187c3141b547 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop6FS.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// for ([|const elem of|] ["a", "b", "c"]) { +//// +//// } +//// } + +verify.codeFixAtPosition("const {} of "); + diff --git a/tests/cases/fourslash/unusedVariableInForLoop7FS.ts b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts new file mode 100644 index 0000000000000..8fd0fee735e27 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInForLoop7FS.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +//// function f1 () { +//// for (const elem of ["a", "b", "c"]) { +//// elem; +//// [|var x = 20;|] +//// } +////} +//// + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInModule1.ts b/tests/cases/fourslash/unusedVariableInModule1.ts new file mode 100644 index 0000000000000..011434ce098df --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInModule1.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// export {} +//// [|var x: string;|] +//// export var y: string; + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInModule2.ts b/tests/cases/fourslash/unusedVariableInModule2.ts new file mode 100644 index 0000000000000..09108ab1ee0f9 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInModule2.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// export {} +//// [|var x: string, y: number;|] +//// y; +//// export var y: string; + +verify.codeFixAtPosition("var y: number;", 6133); diff --git a/tests/cases/fourslash/unusedVariableInModule3.ts b/tests/cases/fourslash/unusedVariableInModule3.ts new file mode 100644 index 0000000000000..bffffc768d355 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInModule3.ts @@ -0,0 +1,9 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// export {} +//// [|var x = function f1() {}|] +//// export var y: string; + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInModule4.ts b/tests/cases/fourslash/unusedVariableInModule4.ts new file mode 100644 index 0000000000000..6a1be9fe5b89a --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInModule4.ts @@ -0,0 +1,10 @@ +/// + +// @noUnusedLocals: true +// @noUnusedParameters: true +//// export {} +//// [|var x = function f1(m: number) {}|] +//// x; +//// export var y: string; + +verify.codeFixAtPosition(`var x = function f1() {}`); diff --git a/tests/cases/fourslash/unusedVariableInNamespace1.ts b/tests/cases/fourslash/unusedVariableInNamespace1.ts new file mode 100644 index 0000000000000..caf778bc0da76 --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInNamespace1.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +////namespace greeter { +//// [|let a = "dummy entry";|] +////} + +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedVariableInNamespace2.ts b/tests/cases/fourslash/unusedVariableInNamespace2.ts new file mode 100644 index 0000000000000..fbb9e2d6a0c2b --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInNamespace2.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +////namespace greeter { +//// [|let a = "dummy entry", b, c = 0;|] +//// export function function1() { +//// a = "dummy"; +//// c++; +//// } +////} + +verify.codeFixAtPosition(`let a = "dummy entry", c = 0;`); diff --git a/tests/cases/fourslash/unusedVariableInNamespace3.ts b/tests/cases/fourslash/unusedVariableInNamespace3.ts new file mode 100644 index 0000000000000..33e501d0c0def --- /dev/null +++ b/tests/cases/fourslash/unusedVariableInNamespace3.ts @@ -0,0 +1,12 @@ +/// + +// @noUnusedLocals: true +////namespace greeter { +//// [|let a = "dummy entry", b, c = 0;|] +//// export function function1() { +//// a = "dummy"; +//// b = 0; +//// } +////} + +verify.codeFixAtPosition(`let a = "dummy entry", b;`); From 03a6eeb6436780c78026c1bbf453feec1d6ba422 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Fri, 21 Oct 2016 14:56:38 -0700 Subject: [PATCH 02/11] Major refactoring after PR feedback --- .../codefixes/unusedIdentifierFixes.ts | 203 ++++++++---------- 1 file changed, 92 insertions(+), 111 deletions(-) diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index 9a69af04bfc83..4c5f0873d5f04 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -10,134 +10,106 @@ namespace ts.codefix { const start = context.span.start; const token = getTokenAtPosition(sourceFile, start); - if (token.kind === ts.SyntaxKind.Identifier) { - if (token.parent.kind === ts.SyntaxKind.VariableDeclaration) { - if (token.parent.parent.parent.kind === SyntaxKind.ForStatement) { - const forStatement = token.parent.parent.parent; - const initializer = forStatement.initializer; - if (initializer.declarations.length === 1) { - return createCodeFix("", initializer.pos, initializer.end - initializer.pos); - } - else { - if (initializer.declarations[0] === token.parent) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + switch (token.kind) { + case ts.SyntaxKind.Identifier: + switch (token.parent.kind) { + case ts.SyntaxKind.VariableDeclaration: + switch (token.parent.parent.parent.kind) { + case SyntaxKind.ForStatement: + const forStatement = token.parent.parent.parent; + const forInitializer = forStatement.initializer; + if (forInitializer.declarations.length === 1) { + return createCodeFix("", forInitializer.pos, forInitializer.end - forInitializer.pos); + } + else { + return removeSingleItem(forInitializer.declarations, token); + } + + case SyntaxKind.ForOfStatement: + case SyntaxKind.ForInStatement: + const forOfStatement = token.parent.parent.parent; + if (forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) { + const forOfInitializer = forOfStatement.initializer; + return createCodeFix("{}", forOfInitializer.declarations[0].pos, forOfInitializer.declarations[0].end - forOfInitializer.declarations[0].pos); + } + break; + + case SyntaxKind.CatchClause: + const catchClause = token.parent.parent; + const parameter = catchClause.variableDeclaration.getChildren()[0]; + return createCodeFix("", parameter.pos, parameter.end - parameter.pos); + + default: + const variableStatement = token.parent.parent.parent; + if (variableStatement.declarationList.declarations.length === 1) { + return createCodeFix("", variableStatement.pos, variableStatement.end - variableStatement.pos); + } + else { + const declarations = variableStatement.declarationList.declarations; + return removeSingleItem(declarations, token); + } + } + + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.ModuleDeclaration: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.ArrowFunction: + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + + case SyntaxKind.TypeParameter: + const typeParameters = (token.parent.parent).typeParameters; + if (typeParameters.length === 1) { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 2); } else { - return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + return removeSingleItem(typeParameters, token); } - } - } - else if (token.parent.parent.parent.kind === SyntaxKind.ForInStatement) { - const forInStatement = token.parent.parent.parent; - const initializer = forInStatement.initializer; - return createCodeFix("{}", initializer.declarations[0].pos, initializer.declarations[0].end - initializer.declarations[0].pos); - } - else if (token.parent.parent.parent.kind === SyntaxKind.ForOfStatement) { - const forOfStatement = token.parent.parent.parent; - const initializer = forOfStatement.initializer; - return createCodeFix("{}", initializer.declarations[0].pos, initializer.declarations[0].end - initializer.declarations[0].pos); - } - else if (token.parent.parent.kind === SyntaxKind.CatchClause) { - const catchClause = token.parent.parent; - const parameter = catchClause.variableDeclaration.getChildren()[0]; - return createCodeFix("", parameter.pos, parameter.end - parameter.pos); - } - else { - const variableStatement = token.parent.parent.parent; - if (variableStatement.declarationList.declarations.length === 1) { - return createCodeFix("", variableStatement.pos, variableStatement.end - variableStatement.pos); - } - else { - const declarations = variableStatement.declarationList.declarations; - if (declarations[0].name === token) { - return createCodeFix("", token.parent.pos + 1, token.parent.end - token.parent.pos); + + case ts.SyntaxKind.Parameter: + const functionDeclaration = token.parent.parent; + if (functionDeclaration.parameters.length === 1) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); } else { - return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + return removeSingleItem(functionDeclaration.parameters, token); } - } - } - } - if (token.parent.kind === SyntaxKind.FunctionDeclaration || - token.parent.kind === SyntaxKind.ClassDeclaration || - token.parent.kind === SyntaxKind.InterfaceDeclaration || - token.parent.kind === SyntaxKind.MethodDeclaration || - token.parent.kind === SyntaxKind.ModuleDeclaration || - token.parent.kind === SyntaxKind.PropertyDeclaration || - token.parent.kind === SyntaxKind.ArrowFunction) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - } + case SyntaxKind.ImportSpecifier: + const namedImports = token.parent.parent; + const elements = namedImports.elements; + if (elements.length === 1) { + // Only 1 import and it is unused. So the entire line could be removed. + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + else { + return removeSingleItem(elements, token); + } - if (token.parent.kind === SyntaxKind.TypeParameter) { - const typeParameters = (token.parent.parent).typeParameters; - if (typeParameters.length === 1) { - return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 2); - } - else { - if (typeParameters[0] === token.parent) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); - } - else { - return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); - } - } - } + case SyntaxKind.ImportEqualsDeclaration: + return createCodeFix("{}", token.pos, token.end - token.pos); - if (token.parent.kind === ts.SyntaxKind.Parameter) { - const functionDeclaration = token.parent.parent; - if (functionDeclaration.parameters.length === 1) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - } - else { - if (functionDeclaration.parameters[0] === token.parent) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); - } - else { - return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); - } + case SyntaxKind.EnumDeclaration: + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); } - } - if (token.parent.kind === SyntaxKind.ImportSpecifier) { - const namedImports = token.parent.parent; - const elements = namedImports.elements; - if (elements.length === 1) { - // Only 1 import and it is unused. So the entire line could be removed. - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + if (token.parent.parent.kind === SyntaxKind.ImportClause || token.parent.parent.kind === SyntaxKind.ImportDeclaration) { + return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); } - else { - if (elements[0] === token.parent) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); - } - else { - return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); - } - } - } - - if (token.parent.parent.kind === SyntaxKind.ImportClause || token.parent.parent.kind === SyntaxKind.ImportDeclaration) { - return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); - } - - if (token.parent.kind === SyntaxKind.ImportEqualsDeclaration) { - return createCodeFix("{}", token.pos, token.end - token.pos); - } + break; - if (token.parent.kind === SyntaxKind.EnumDeclaration) { + case SyntaxKind.PrivateKeyword: + case SyntaxKind.PropertyDeclaration: return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - } - } - if (token.kind === SyntaxKind.PrivateKeyword && token.parent.kind === SyntaxKind.PropertyDeclaration) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - } - - if (token.kind === SyntaxKind.AsteriskToken && token.parent.kind === SyntaxKind.NamespaceImport) { - return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); + case SyntaxKind.AsteriskToken: + case SyntaxKind.NamespaceImport: + return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); } - return undefined; + return []; function createCodeFix(newText: string, start: number, length: number): CodeAction[] { return [{ @@ -148,6 +120,15 @@ namespace ts.codefix { }] }]; } + + function removeSingleItem(elements: NodeArray, token: T): CodeAction[] { + if (elements[0] === token.parent) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos + 1); + } + else { + return createCodeFix("", token.parent.pos - 1, token.parent.end - token.parent.pos + 1); + } + } } }); } From 79fa9dbc5f21fdd1f70feaa37a9960dd04762bf7 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Fri, 21 Oct 2016 15:48:24 -0700 Subject: [PATCH 03/11] Add tests for different constructor parameter cases. --- tests/cases/fourslash/unusedParameterInConstructor2.ts | 8 ++++++++ tests/cases/fourslash/unusedParameterInConstructor3.ts | 8 ++++++++ tests/cases/fourslash/unusedParameterInConstructor4.ts | 8 ++++++++ 3 files changed, 24 insertions(+) create mode 100644 tests/cases/fourslash/unusedParameterInConstructor2.ts create mode 100644 tests/cases/fourslash/unusedParameterInConstructor3.ts create mode 100644 tests/cases/fourslash/unusedParameterInConstructor4.ts diff --git a/tests/cases/fourslash/unusedParameterInConstructor2.ts b/tests/cases/fourslash/unusedParameterInConstructor2.ts new file mode 100644 index 0000000000000..bd5f66ff96685 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInConstructor2.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|constructor(public p1: string, private p2: boolean, public p3: any, p5)|] { p5; } +//// } + +verify.codeFixAtPosition("constructor(public p1: string, public p3: any, p5)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInConstructor3.ts b/tests/cases/fourslash/unusedParameterInConstructor3.ts new file mode 100644 index 0000000000000..173e00113d8f0 --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInConstructor3.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|constructor(public p1: string, public p2: boolean, private p3: any, p5)|] { p5; } +//// } + +verify.codeFixAtPosition("constructor(public p1: string, public p2: boolean, p5)"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedParameterInConstructor4.ts b/tests/cases/fourslash/unusedParameterInConstructor4.ts new file mode 100644 index 0000000000000..6d0223dc5f4fd --- /dev/null +++ b/tests/cases/fourslash/unusedParameterInConstructor4.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// class C1 { +//// [|constructor(private readonly p2: boolean, p5)|] { p5; } +//// } + +verify.codeFixAtPosition("constructor(p5)"); \ No newline at end of file From 1f94e14d84d60caf9e634ba334636e4438c5a0a3 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Fri, 21 Oct 2016 17:11:32 -0700 Subject: [PATCH 04/11] Remove unused case, and fix for..in --- src/services/codefixes/unusedIdentifierFixes.ts | 11 +++++++---- tests/cases/fourslash/unusedVariableInForLoop5FS.ts | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index 4c5f0873d5f04..8e76f95a3d3e6 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -26,14 +26,18 @@ namespace ts.codefix { } case SyntaxKind.ForOfStatement: - case SyntaxKind.ForInStatement: - const forOfStatement = token.parent.parent.parent; + const forOfStatement = token.parent.parent.parent; if (forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList) { const forOfInitializer = forOfStatement.initializer; return createCodeFix("{}", forOfInitializer.declarations[0].pos, forOfInitializer.declarations[0].end - forOfInitializer.declarations[0].pos); } break; + case SyntaxKind.ForInStatement: + // There is no valid fix in the case of: + // for .. in + return undefined; + case SyntaxKind.CatchClause: const catchClause = token.parent.parent; const parameter = catchClause.variableDeclaration.getChildren()[0]; @@ -56,7 +60,6 @@ namespace ts.codefix { case SyntaxKind.MethodDeclaration: case SyntaxKind.ModuleDeclaration: case SyntaxKind.PropertyDeclaration: - case SyntaxKind.ArrowFunction: return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); case SyntaxKind.TypeParameter: @@ -109,7 +112,7 @@ namespace ts.codefix { return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); } - return []; + return undefined; function createCodeFix(newText: string, start: number, length: number): CodeAction[] { return [{ diff --git a/tests/cases/fourslash/unusedVariableInForLoop5FS.ts b/tests/cases/fourslash/unusedVariableInForLoop5FS.ts index 60369da522d17..23df03480e3ef 100644 --- a/tests/cases/fourslash/unusedVariableInForLoop5FS.ts +++ b/tests/cases/fourslash/unusedVariableInForLoop5FS.ts @@ -2,10 +2,10 @@ // @noUnusedLocals: true //// function f1 () { -//// for ([|const elem in|] ["a", "b", "c"]) { +//// for (const elem in ["a", "b", "c"]) { //// //// } //// } -verify.codeFixAtPosition("const {} in "); +verify.not.codeFixAvailable(); From 409787495e09b9ba37c903d1233b73ddd079af15 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Mon, 24 Oct 2016 11:40:23 -0700 Subject: [PATCH 05/11] Fix 'import a = A' case --- src/services/codefixes/unusedIdentifierFixes.ts | 5 ++++- tests/cases/fourslash/unusedImports10FS.ts | 2 +- tests/cases/fourslash/unusedImports9FS.ts | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index 8e76f95a3d3e6..f801d5182d8e8 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -91,8 +91,11 @@ namespace ts.codefix { return removeSingleItem(elements, token); } + // handle case where 'import a = A;' + // remove entire line case SyntaxKind.ImportEqualsDeclaration: - return createCodeFix("{}", token.pos, token.end - token.pos); + const importDecl = token.parent; + return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos); case SyntaxKind.EnumDeclaration: return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); diff --git a/tests/cases/fourslash/unusedImports10FS.ts b/tests/cases/fourslash/unusedImports10FS.ts index 2eb923c9b8fbc..f9d38e4cfb0ef 100644 --- a/tests/cases/fourslash/unusedImports10FS.ts +++ b/tests/cases/fourslash/unusedImports10FS.ts @@ -12,5 +12,5 @@ //// [|import a = A;|] //// } -verify.codeFixAtPosition(" import {} = A;"); +verify.codeFixAtPosition(""); diff --git a/tests/cases/fourslash/unusedImports9FS.ts b/tests/cases/fourslash/unusedImports9FS.ts index 2ba30c95bb718..324d57a1928c4 100644 --- a/tests/cases/fourslash/unusedImports9FS.ts +++ b/tests/cases/fourslash/unusedImports9FS.ts @@ -17,4 +17,4 @@ //// //// } -verify.codeFixAtPosition("import {} = require('./file1')"); \ No newline at end of file +verify.codeFixAtPosition(""); \ No newline at end of file From d4b99d66e07625124891177b0ceec38473af0f31 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Mon, 24 Oct 2016 17:32:58 -0700 Subject: [PATCH 06/11] Simplifying handling import cases --- .../codefixes/unusedIdentifierFixes.ts | 18 ++++++++++-------- tests/cases/fourslash/unusedImports11FS.ts | 14 ++++++++++++++ tests/cases/fourslash/unusedImports12FS.ts | 13 +++++++++++++ tests/cases/fourslash/unusedImports1FS.ts | 4 ++-- tests/cases/fourslash/unusedImports2FS.ts | 3 +-- tests/cases/fourslash/unusedImports3FS.ts | 2 +- tests/cases/fourslash/unusedImports4FS.ts | 2 +- tests/cases/fourslash/unusedImports6FS.ts | 2 +- tests/cases/fourslash/unusedImports7FS.ts | 6 +----- 9 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 tests/cases/fourslash/unusedImports11FS.ts create mode 100644 tests/cases/fourslash/unusedImports12FS.ts diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index f801d5182d8e8..bb3664b974e74 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -92,18 +92,20 @@ namespace ts.codefix { } // handle case where 'import a = A;' - // remove entire line case SyntaxKind.ImportEqualsDeclaration: - const importDecl = token.parent; - return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos); + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + + // handle case where 'import d from './file' + case SyntaxKind.ImportClause: + return createCodeFix("", token.parent.parent.pos, token.parent.parent.end - token.parent.parent.pos); + + // handle case where 'import * as a from './file' + case SyntaxKind.NamespaceImport: + return createCodeFix("", token.parent.parent.parent.pos, token.parent.parent.parent.end - token.parent.parent.parent.pos); case SyntaxKind.EnumDeclaration: return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); } - - if (token.parent.parent.kind === SyntaxKind.ImportClause || token.parent.parent.kind === SyntaxKind.ImportDeclaration) { - return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); - } break; case SyntaxKind.PrivateKeyword: @@ -112,7 +114,7 @@ namespace ts.codefix { case SyntaxKind.AsteriskToken: case SyntaxKind.NamespaceImport: - return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); } return undefined; diff --git a/tests/cases/fourslash/unusedImports11FS.ts b/tests/cases/fourslash/unusedImports11FS.ts new file mode 100644 index 0000000000000..a18a4634d719b --- /dev/null +++ b/tests/cases/fourslash/unusedImports11FS.ts @@ -0,0 +1,14 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import f1, * as s from "./file1"; |] +//// s.f2('hello'); + +// @Filename: file1.ts +//// export var v1; +//// export function f1(n: number){} +//// export function f2(s: string){}; +//// export default f1; + +verify.codeFixAtPosition('import * as s from "./file1";'); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports12FS.ts b/tests/cases/fourslash/unusedImports12FS.ts new file mode 100644 index 0000000000000..647b7dfbe16d8 --- /dev/null +++ b/tests/cases/fourslash/unusedImports12FS.ts @@ -0,0 +1,13 @@ +/// + +// @noUnusedLocals: true +// @Filename: file2.ts +//// [| import f1, * as s from "./file1"; |] +//// f1(42); + +// @Filename: file1.ts +//// export function f1(n: number){} +//// export function f2(s: string){}; +//// export default f1; + +verify.codeFixAtPosition('import f1 "./file1";'); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports1FS.ts b/tests/cases/fourslash/unusedImports1FS.ts index c3ae198d876dc..411e9b3530b53 100644 --- a/tests/cases/fourslash/unusedImports1FS.ts +++ b/tests/cases/fourslash/unusedImports1FS.ts @@ -2,11 +2,11 @@ // @noUnusedLocals: true // @Filename: file2.ts -//// [| import {/*0*/Calculator/*1*/} from "./file1" |] +//// [| import { Calculator } from "./file1" |] // @Filename: file1.ts //// export class Calculator { //// //// } -verify.codeFixAtPosition(`import {} from "./file1"`); +verify.codeFixAtPosition(''); diff --git a/tests/cases/fourslash/unusedImports2FS.ts b/tests/cases/fourslash/unusedImports2FS.ts index a7144d1eb4976..a27f568b0d21d 100644 --- a/tests/cases/fourslash/unusedImports2FS.ts +++ b/tests/cases/fourslash/unusedImports2FS.ts @@ -16,5 +16,4 @@ //// //// } -verify.codeFixAtPosition(`import {Calculator} from "./file1" -import {} from "./file1"`); +verify.codeFixAtPosition(`import {Calculator} from "./file1"`); diff --git a/tests/cases/fourslash/unusedImports3FS.ts b/tests/cases/fourslash/unusedImports3FS.ts index f030232dc1e5b..205666e971d84 100644 --- a/tests/cases/fourslash/unusedImports3FS.ts +++ b/tests/cases/fourslash/unusedImports3FS.ts @@ -2,7 +2,7 @@ // @noUnusedLocals: true // @Filename: file2.ts -////[| import {/*0*/Calculator,/*1*/ test, test2} from "./file1" |] +////[| import {Calculator, test, test2} from "./file1" |] //// test(); //// test2(); diff --git a/tests/cases/fourslash/unusedImports4FS.ts b/tests/cases/fourslash/unusedImports4FS.ts index ab37928eb0164..302007748f442 100644 --- a/tests/cases/fourslash/unusedImports4FS.ts +++ b/tests/cases/fourslash/unusedImports4FS.ts @@ -2,7 +2,7 @@ // @noUnusedLocals: true // @Filename: file2.ts -//// [| import {Calculator/*0*/, test/*1*/, test2} from "./file1" |] +//// [| import {Calculator, test, test2} from "./file1" |] //// //// var x = new Calculator(); //// x.handleChar(); diff --git a/tests/cases/fourslash/unusedImports6FS.ts b/tests/cases/fourslash/unusedImports6FS.ts index c8e1af9231389..a5c6744855af2 100644 --- a/tests/cases/fourslash/unusedImports6FS.ts +++ b/tests/cases/fourslash/unusedImports6FS.ts @@ -17,4 +17,4 @@ //// //// } -verify.codeFixAtPosition(`import {} from "./file1"`); \ No newline at end of file +verify.codeFixAtPosition(''); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports7FS.ts b/tests/cases/fourslash/unusedImports7FS.ts index 6dc0886e8ffbe..23066ef538d55 100644 --- a/tests/cases/fourslash/unusedImports7FS.ts +++ b/tests/cases/fourslash/unusedImports7FS.ts @@ -8,13 +8,9 @@ //// export class Calculator { //// handleChar() { } //// } -//// //// export function test() { -//// //// } -//// //// export default function test2() { -//// //// } -verify.codeFixAtPosition(`import {} from "./file1"`); \ No newline at end of file +verify.codeFixAtPosition(''); \ No newline at end of file From b59714ea7e808c4afe82e7fba38d77a893d1ea02 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Tue, 1 Nov 2016 16:31:23 -0700 Subject: [PATCH 07/11] Add more testcases and simplify --- .../codefixes/unusedIdentifierFixes.ts | 14 +++++----- .../fourslash/unusedClassInNamespace3.ts | 19 ++++++++++--- .../fourslash/unusedClassInNamespace4.ts | 12 +++++++-- .../fourslash/unusedClassInNamespace5.ts | 26 ------------------ .../fourslash/unusedClassInNamespace6.ts | 27 ------------------- .../cases/fourslash/unusedEnumInNamespace1.ts | 11 ++++++++ .../fourslash/unusedTypeAliasInNamespace1.ts | 11 ++++++++ 7 files changed, 54 insertions(+), 66 deletions(-) delete mode 100644 tests/cases/fourslash/unusedClassInNamespace5.ts delete mode 100644 tests/cases/fourslash/unusedClassInNamespace6.ts create mode 100644 tests/cases/fourslash/unusedEnumInNamespace1.ts create mode 100644 tests/cases/fourslash/unusedTypeAliasInNamespace1.ts diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index bb3664b974e74..1f6dcb5535f98 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -54,14 +54,6 @@ namespace ts.codefix { } } - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.MethodDeclaration: - case SyntaxKind.ModuleDeclaration: - case SyntaxKind.PropertyDeclaration: - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - case SyntaxKind.TypeParameter: const typeParameters = (token.parent.parent).typeParameters; if (typeParameters.length === 1) { @@ -105,6 +97,12 @@ namespace ts.codefix { case SyntaxKind.EnumDeclaration: return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + + default: + if (isDeclarationName(token)) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + break; } break; diff --git a/tests/cases/fourslash/unusedClassInNamespace3.ts b/tests/cases/fourslash/unusedClassInNamespace3.ts index 6102f744717d6..391c5e833efac 100644 --- a/tests/cases/fourslash/unusedClassInNamespace3.ts +++ b/tests/cases/fourslash/unusedClassInNamespace3.ts @@ -5,8 +5,21 @@ //// [| namespace Validation { //// class c1 { //// -//// }/*1*/ -//// } |] +//// } +//// +//// export class c2 { +//// +//// } +//// +//// class c3 extends c1 { +//// +//// } +////} |] verify.codeFixAtPosition(`namespace Validation { -}`); \ No newline at end of file + class c1 { + } + + export class c2 { + } +}`); diff --git a/tests/cases/fourslash/unusedClassInNamespace4.ts b/tests/cases/fourslash/unusedClassInNamespace4.ts index 79701a5e0e20f..5db5b1aefa65d 100644 --- a/tests/cases/fourslash/unusedClassInNamespace4.ts +++ b/tests/cases/fourslash/unusedClassInNamespace4.ts @@ -2,7 +2,6 @@ // @noUnusedLocals: true // @noUnusedParameters:true - //// [| namespace Validation { //// class c1 { //// @@ -11,9 +10,18 @@ //// export class c2 { //// //// } -//// } |] +//// +//// class c3 { +//// public x: c1; +//// } +////} |] verify.codeFixAtPosition(`namespace Validation { + class c1 { + + } + export class c2 { + } }`); diff --git a/tests/cases/fourslash/unusedClassInNamespace5.ts b/tests/cases/fourslash/unusedClassInNamespace5.ts deleted file mode 100644 index 80d8fe857bd12..0000000000000 --- a/tests/cases/fourslash/unusedClassInNamespace5.ts +++ /dev/null @@ -1,26 +0,0 @@ -/// - -// @noUnusedLocals: true -// @noUnusedParameters:true - -//// [| namespace Validation { -//// class c1 { -//// -//// } -//// -//// export class c2 { -//// -//// } -//// -//// class c3 extends c1 { -//// -//// } -////} |] - -verify.codeFixAtPosition(`namespace Validation { - class c1 { - } - - export class c2 { - } -}`); diff --git a/tests/cases/fourslash/unusedClassInNamespace6.ts b/tests/cases/fourslash/unusedClassInNamespace6.ts deleted file mode 100644 index 5db5b1aefa65d..0000000000000 --- a/tests/cases/fourslash/unusedClassInNamespace6.ts +++ /dev/null @@ -1,27 +0,0 @@ -/// - -// @noUnusedLocals: true -// @noUnusedParameters:true -//// [| namespace Validation { -//// class c1 { -//// -//// } -//// -//// export class c2 { -//// -//// } -//// -//// class c3 { -//// public x: c1; -//// } -////} |] - -verify.codeFixAtPosition(`namespace Validation { - class c1 { - - } - - export class c2 { - - } -}`); diff --git a/tests/cases/fourslash/unusedEnumInNamespace1.ts b/tests/cases/fourslash/unusedEnumInNamespace1.ts new file mode 100644 index 0000000000000..88e8e32d5f867 --- /dev/null +++ b/tests/cases/fourslash/unusedEnumInNamespace1.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// enum enum1 { +//// Monday +//// } +//// } |] + +verify.codeFixAtPosition(`namespace greeter { +}`); diff --git a/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts b/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts new file mode 100644 index 0000000000000..593c0fe8cf433 --- /dev/null +++ b/tests/cases/fourslash/unusedTypeAliasInNamespace1.ts @@ -0,0 +1,11 @@ +/// + +// @noUnusedLocals: true +//// [| namespace greeter { +//// type hw = "Hello" |"world"; +//// export type nw = "No" | "Way"; +//// } |] + +verify.codeFixAtPosition(`namespace greeter { + export type nw = "No" | "Way"; +}`); From 71960187cdea4901b1ffa95afb0015d183f4badb Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Tue, 1 Nov 2016 16:39:29 -0700 Subject: [PATCH 08/11] Removed unused, confusing cases --- src/services/codefixes/unusedIdentifierFixes.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index 1f6dcb5535f98..1e8220d4b7a95 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -95,9 +95,6 @@ namespace ts.codefix { case SyntaxKind.NamespaceImport: return createCodeFix("", token.parent.parent.parent.pos, token.parent.parent.parent.end - token.parent.parent.parent.pos); - case SyntaxKind.EnumDeclaration: - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - default: if (isDeclarationName(token)) { return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); @@ -106,11 +103,9 @@ namespace ts.codefix { } break; - case SyntaxKind.PrivateKeyword: case SyntaxKind.PropertyDeclaration: return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - case SyntaxKind.AsteriskToken: case SyntaxKind.NamespaceImport: return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); } From 2f453ce674c6f3f35610215ffc8944e0ca8b3281 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Thu, 3 Nov 2016 12:48:28 -0700 Subject: [PATCH 09/11] Handle most module cases --- src/harness/fourslash.ts | 2 +- .../codefixes/unusedIdentifierFixes.ts | 89 ++++++++++++++----- tests/cases/fourslash/unusedImports12FS.ts | 2 +- tests/cases/fourslash/unusedImports1FS.ts | 2 +- tests/cases/fourslash/unusedImports2FS.ts | 4 +- tests/cases/fourslash/unusedMethodInClass5.ts | 8 ++ tests/cases/fourslash/unusedMethodInClass6.ts | 8 ++ 7 files changed, 89 insertions(+), 26 deletions(-) create mode 100644 tests/cases/fourslash/unusedMethodInClass5.ts create mode 100644 tests/cases/fourslash/unusedMethodInClass6.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index e58a189c923fc..fb1545d6aa45f 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -2055,7 +2055,7 @@ namespace FourSlash { const diagnostic = !errorCode ? diagnostics[0] : ts.find(diagnostics, d => d.code == errorCode); - return this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.length, [diagnostic.code]); + return this.languageService.getCodeFixesAtPosition(fileName, diagnostic.start, diagnostic.start + diagnostic.length, [diagnostic.code]); } public verifyCodeFixAtPosition(expectedText: string, errorCode?: number) { diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index 1e8220d4b7a95..e563b78583ff2 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -8,7 +8,13 @@ namespace ts.codefix { getCodeActions: (context: CodeFixContext) => { const sourceFile = context.sourceFile; const start = context.span.start; - const token = getTokenAtPosition(sourceFile, start); + + let token = getTokenAtPosition(sourceFile, start); + + // this handles var ["computed"] = 12; + if (token.kind === SyntaxKind.OpenBracketToken) { + token = getTokenAtPosition(sourceFile, start + 1); + } switch (token.kind) { case ts.SyntaxKind.Identifier: @@ -72,34 +78,43 @@ namespace ts.codefix { return removeSingleItem(functionDeclaration.parameters, token); } + // handle case where 'import a = A;' + case SyntaxKind.ImportEqualsDeclaration: + let importEquals = findImportDeclaration(token); + return createCodeFix("", importEquals.pos, importEquals.end - importEquals.pos); + case SyntaxKind.ImportSpecifier: const namedImports = token.parent.parent; - const elements = namedImports.elements; - if (elements.length === 1) { - // Only 1 import and it is unused. So the entire line could be removed. - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + if (namedImports.elements.length === 1) { + // Only 1 import and it is unused. So the entire declaration should be removed. + let importSpec = findImportDeclaration(token); + return createCodeFix("", importSpec.pos, importSpec.end - importSpec.pos); } else { - return removeSingleItem(elements, token); + return removeSingleItem(namedImports.elements, token); } - // handle case where 'import a = A;' - case SyntaxKind.ImportEqualsDeclaration: - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); - - // handle case where 'import d from './file' - case SyntaxKind.ImportClause: - return createCodeFix("", token.parent.parent.pos, token.parent.parent.end - token.parent.parent.pos); + // handle case where "import d, * as ns from './file'" + // or "'import {a, b as ns} from './file'" + case SyntaxKind.ImportClause: // this covers both 'import |d|' and 'import |d,| *' + const importClause = token.parent; + if (!importClause.namedBindings) { // |import d from './file'| or |import * as ns from './file'| + const importDecl = findImportDeclaration(importClause); + return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos); + } + else { // import |d,| * as ns from './file' + return createCodeFix("", importClause.name.pos, importClause.namedBindings.pos - importClause.name.pos); + } - // handle case where 'import * as a from './file' case SyntaxKind.NamespaceImport: - return createCodeFix("", token.parent.parent.parent.pos, token.parent.parent.parent.end - token.parent.parent.parent.pos); - - default: - if (isDeclarationName(token)) { - return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + const namespaceImport = token.parent; + if(namespaceImport.name == token && !(namespaceImport.parent).name){ + const importDecl = findImportDeclaration(namespaceImport); + return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos); + } else { + const start = (namespaceImport.parent).name.end; + return createCodeFix("", start, (namespaceImport.parent).namedBindings.end - start); } - break; } break; @@ -109,8 +124,24 @@ namespace ts.codefix { case SyntaxKind.NamespaceImport: return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); } + if (isDeclarationName(token)) { + return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); + } + else if (isLiteralComputedPropertyDeclarationName(token)) { + return createCodeFix("", token.parent.parent.pos, token.parent.parent.end - token.parent.parent.pos); + } + else { + return undefined; + } - return undefined; + function findImportDeclaration(token: Node): Node { + let importDecl = token; + while (importDecl.kind != SyntaxKind.ImportDeclaration && importDecl.parent) { + importDecl = importDecl.parent; + } + + return importDecl; + } function createCodeFix(newText: string, start: number, length: number): CodeAction[] { return [{ @@ -133,3 +164,19 @@ namespace ts.codefix { } }); } + +const s = "hello"; + +class C { + + + + private ["string"]: string; + private "b iz": string; + + bar() { + this + } +} + + diff --git a/tests/cases/fourslash/unusedImports12FS.ts b/tests/cases/fourslash/unusedImports12FS.ts index 647b7dfbe16d8..4d8243eb4abf0 100644 --- a/tests/cases/fourslash/unusedImports12FS.ts +++ b/tests/cases/fourslash/unusedImports12FS.ts @@ -10,4 +10,4 @@ //// export function f2(s: string){}; //// export default f1; -verify.codeFixAtPosition('import f1 "./file1";'); \ No newline at end of file +verify.codeFixAtPosition('import f1 from "./file1";'); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedImports1FS.ts b/tests/cases/fourslash/unusedImports1FS.ts index 411e9b3530b53..d9fc17a244846 100644 --- a/tests/cases/fourslash/unusedImports1FS.ts +++ b/tests/cases/fourslash/unusedImports1FS.ts @@ -2,7 +2,7 @@ // @noUnusedLocals: true // @Filename: file2.ts -//// [| import { Calculator } from "./file1" |] +//// [|import { Calculator } from "./file1" |] // @Filename: file1.ts //// export class Calculator { diff --git a/tests/cases/fourslash/unusedImports2FS.ts b/tests/cases/fourslash/unusedImports2FS.ts index a27f568b0d21d..6e3d9527c52e2 100644 --- a/tests/cases/fourslash/unusedImports2FS.ts +++ b/tests/cases/fourslash/unusedImports2FS.ts @@ -2,8 +2,8 @@ // @noUnusedLocals: true // @Filename: file2.ts -//// [| import {Calculator} from "./file1" -//// import {test} from "./file1" |] +//// [|import {Calculator} from "./file1" +//// import {test} from "./file1"|] //// var x = new Calculator(); //// x.handleChar(); diff --git a/tests/cases/fourslash/unusedMethodInClass5.ts b/tests/cases/fourslash/unusedMethodInClass5.ts new file mode 100644 index 0000000000000..36ef3670cac0e --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass5.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// [|class C { +//// private ["string"] (){} +//// }|] + +verify.codeFixAtPosition("class C { }"); \ No newline at end of file diff --git a/tests/cases/fourslash/unusedMethodInClass6.ts b/tests/cases/fourslash/unusedMethodInClass6.ts new file mode 100644 index 0000000000000..71fcb92d037b8 --- /dev/null +++ b/tests/cases/fourslash/unusedMethodInClass6.ts @@ -0,0 +1,8 @@ +/// + +// @noUnusedLocals: true +//// [|class C { +//// private "string" (){} +//// }|] + +verify.codeFixAtPosition("class C { }"); \ No newline at end of file From 40c0cbd7b58ed17f5cd3d7e1fe5e2220552aa9ac Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Thu, 3 Nov 2016 13:28:08 -0700 Subject: [PATCH 10/11] Clean up --- .../codefixes/unusedIdentifierFixes.ts | 27 +++++-------------- src/services/tsconfig.json | 2 +- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/src/services/codefixes/unusedIdentifierFixes.ts b/src/services/codefixes/unusedIdentifierFixes.ts index e563b78583ff2..8e14bdcb73e26 100644 --- a/src/services/codefixes/unusedIdentifierFixes.ts +++ b/src/services/codefixes/unusedIdentifierFixes.ts @@ -80,14 +80,14 @@ namespace ts.codefix { // handle case where 'import a = A;' case SyntaxKind.ImportEqualsDeclaration: - let importEquals = findImportDeclaration(token); + const importEquals = findImportDeclaration(token); return createCodeFix("", importEquals.pos, importEquals.end - importEquals.pos); case SyntaxKind.ImportSpecifier: const namedImports = token.parent.parent; if (namedImports.elements.length === 1) { // Only 1 import and it is unused. So the entire declaration should be removed. - let importSpec = findImportDeclaration(token); + const importSpec = findImportDeclaration(token); return createCodeFix("", importSpec.pos, importSpec.end - importSpec.pos); } else { @@ -108,10 +108,11 @@ namespace ts.codefix { case SyntaxKind.NamespaceImport: const namespaceImport = token.parent; - if(namespaceImport.name == token && !(namespaceImport.parent).name){ + if (namespaceImport.name == token && !(namespaceImport.parent).name) { const importDecl = findImportDeclaration(namespaceImport); return createCodeFix("", importDecl.pos, importDecl.end - importDecl.pos); - } else { + } + else { const start = (namespaceImport.parent).name.end; return createCodeFix("", start, (namespaceImport.parent).namedBindings.end - start); } @@ -163,20 +164,4 @@ namespace ts.codefix { } } }); -} - -const s = "hello"; - -class C { - - - - private ["string"]: string; - private "b iz": string; - - bar() { - this - } -} - - +} \ No newline at end of file diff --git a/src/services/tsconfig.json b/src/services/tsconfig.json index 0066ef94343d1..17ca5ac973931 100644 --- a/src/services/tsconfig.json +++ b/src/services/tsconfig.json @@ -1,4 +1,4 @@ -{ +{ "compilerOptions": { "noImplicitAny": true, "noImplicitThis": true, From 78fdd44dd1fc352129314b580a27019ccd9ba496 Mon Sep 17 00:00:00 2001 From: Paul van Brenk Date: Mon, 7 Nov 2016 13:01:14 -0800 Subject: [PATCH 11/11] Remove error-codes from fourslash tests --- tests/cases/fourslash/unusedFunctionInNamespace5.ts | 4 ++-- tests/cases/fourslash/unusedLocalsInFunction2.ts | 4 ++-- tests/cases/fourslash/unusedLocalsInFunction3.ts | 4 ++-- tests/cases/fourslash/unusedVariableInModule2.ts | 6 +++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/cases/fourslash/unusedFunctionInNamespace5.ts b/tests/cases/fourslash/unusedFunctionInNamespace5.ts index fa1eed2364a51..b839d9dcd976b 100644 --- a/tests/cases/fourslash/unusedFunctionInNamespace5.ts +++ b/tests/cases/fourslash/unusedFunctionInNamespace5.ts @@ -18,11 +18,11 @@ //// //// } //// -//// exp ort let a = function3; |] +//// export let a = function3; |] ////} verify.codeFixAtPosition(`function function3() { function1(); } - export let a = function3;`, 6133); + export let a = function3;`); diff --git a/tests/cases/fourslash/unusedLocalsInFunction2.ts b/tests/cases/fourslash/unusedLocalsInFunction2.ts index 8f84362397461..b709432804118 100644 --- a/tests/cases/fourslash/unusedLocalsInFunction2.ts +++ b/tests/cases/fourslash/unusedLocalsInFunction2.ts @@ -3,7 +3,7 @@ // @noUnusedLocals: true ////function greeter() { //// [| var x, y = 0; |] -//// x++; +//// x+1; ////} -verify.codeFixAtPosition("var x;", 6133); +verify.codeFixAtPosition("var x;"); diff --git a/tests/cases/fourslash/unusedLocalsInFunction3.ts b/tests/cases/fourslash/unusedLocalsInFunction3.ts index 3fc925413900b..906517ee0a78b 100644 --- a/tests/cases/fourslash/unusedLocalsInFunction3.ts +++ b/tests/cases/fourslash/unusedLocalsInFunction3.ts @@ -3,8 +3,8 @@ // @noUnusedLocals: true ////function greeter() { //// [| var x, y = 0,z = 1; |] -//// x++; -//// z++; +//// x+1; +//// z+1; ////} verify.codeFixAtPosition("var x,z = 1;", 6133); diff --git a/tests/cases/fourslash/unusedVariableInModule2.ts b/tests/cases/fourslash/unusedVariableInModule2.ts index 09108ab1ee0f9..db4519c8faac7 100644 --- a/tests/cases/fourslash/unusedVariableInModule2.ts +++ b/tests/cases/fourslash/unusedVariableInModule2.ts @@ -3,8 +3,8 @@ // @noUnusedLocals: true // @noUnusedParameters: true //// export {} -//// [|var x: string, y: number;|] -//// y; +//// [|var x: string, z: number;|] +//// z; //// export var y: string; -verify.codeFixAtPosition("var y: number;", 6133); +verify.codeFixAtPosition("var z: number;");