From b9885eed5a2df9713f703774d63e65d3d4342f56 Mon Sep 17 00:00:00 2001 From: Arthur Ozga Date: Thu, 8 Jun 2017 18:43:02 -0700 Subject: [PATCH] Only add underscore in * for-in * for-of * parameters --- src/services/codefixes/fixUnusedIdentifier.ts | 68 +++++++++---------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index c3e7e2bb4f2..cbe2ba5b1c5 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -18,16 +18,14 @@ namespace ts.codefix { switch (token.kind) { case ts.SyntaxKind.Identifier: - let actions = deleteIdentifier(token); - (actions || (actions = [])).push(prefixIdentifierWithUnderscore(token)); - return actions; + return deleteIdentifierOrPrefixWithUnderscore(token); case SyntaxKind.PropertyDeclaration: case SyntaxKind.NamespaceImport: - return deleteNode(token.parent); + return [deleteNode(token.parent)]; default: - return deleteDefault(); + return [deleteDefault()]; } function deleteDefault() { @@ -43,7 +41,6 @@ namespace ts.codefix { } function prefixIdentifierWithUnderscore(identifier: Identifier): CodeAction { - // TODO: make sure this work with prefixing trivia. const startPosition = identifier.getStart(sourceFile, /*includeJsDocComment*/ false); return { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Prefix_0_with_an_underscore), { 0: token.getText() }), @@ -57,11 +54,11 @@ namespace ts.codefix { }; } - function deleteIdentifier(identifier: Identifier): CodeAction[] | undefined { + function deleteIdentifierOrPrefixWithUnderscore(identifier: Identifier): CodeAction[] | undefined { const parent = identifier.parent; switch (parent.kind) { case ts.SyntaxKind.VariableDeclaration: - return deleteVariableDeclaration(parent); + return deleteVariableDeclarationOrPrefixWithUnderscore(identifier, parent); case SyntaxKind.TypeParameter: const typeParameters = (parent.parent).typeParameters; @@ -71,33 +68,32 @@ namespace ts.codefix { Debug.assert(previousToken.kind === SyntaxKind.LessThanToken); Debug.assert(nextToken.kind === SyntaxKind.GreaterThanToken); - return deleteNodeRange(previousToken, nextToken); + return [deleteNodeRange(previousToken, nextToken)]; } else { - return deleteNodeInList(parent); + return [deleteNodeInList(parent)]; } case ts.SyntaxKind.Parameter: const functionDeclaration = parent.parent; - return functionDeclaration.parameters.length === 1 ? - deleteNode(parent) : - deleteNodeInList(parent); + return [functionDeclaration.parameters.length === 1 ? deleteNode(parent) : deleteNodeInList(parent), + prefixIdentifierWithUnderscore(identifier)]; // handle case where 'import a = A;' case SyntaxKind.ImportEqualsDeclaration: const importEquals = getAncestor(identifier, SyntaxKind.ImportEqualsDeclaration); - return deleteNode(importEquals); + return [deleteNode(importEquals)]; case SyntaxKind.ImportSpecifier: const namedImports = parent.parent; if (namedImports.elements.length === 1) { // Only 1 import and it is unused. So the entire declaration should be removed. const importSpec = getAncestor(identifier, SyntaxKind.ImportDeclaration); - return deleteNode(importSpec); + return [deleteNode(importSpec)]; } else { // delete import specifier - return deleteNodeInList(parent); + return [deleteNodeInList(parent)]; } // handle case where "import d, * as ns from './file'" @@ -106,7 +102,7 @@ namespace ts.codefix { const importClause = parent; if (!importClause.namedBindings) { // |import d from './file'| or |import * as ns from './file'| const importDecl = getAncestor(importClause, SyntaxKind.ImportDeclaration); - return deleteNode(importDecl); + return [deleteNode(importDecl)]; } else { // import |d,| * as ns from './file' @@ -114,10 +110,10 @@ namespace ts.codefix { const nextToken = getTokenAtPosition(sourceFile, importClause.name.end, /*includeJsDocComment*/ false); if (nextToken && nextToken.kind === SyntaxKind.CommaToken) { // shift first non-whitespace position after comma to the start position of the node - return deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) }); + return [deleteRange({ pos: start, end: skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true) })]; } else { - return deleteNode(importClause.name); + return [deleteNode(importClause.name)]; } } @@ -125,53 +121,51 @@ namespace ts.codefix { const namespaceImport = parent; if (namespaceImport.name === identifier && !(namespaceImport.parent).name) { const importDecl = getAncestor(namespaceImport, SyntaxKind.ImportDeclaration); - return deleteNode(importDecl); + return [deleteNode(importDecl)]; } else { const previousToken = getTokenAtPosition(sourceFile, namespaceImport.pos - 1, /*includeJsDocComment*/ false); if (previousToken && previousToken.kind === SyntaxKind.CommaToken) { const startPosition = textChanges.getAdjustedStartPosition(sourceFile, previousToken, {}, textChanges.Position.FullStart); - return deleteRange({ pos: startPosition, end: namespaceImport.end }); + return [deleteRange({ pos: startPosition, end: namespaceImport.end })]; } - return deleteRange(namespaceImport); + return [deleteRange(namespaceImport)]; } default: - return deleteDefault(); + return [deleteDefault()]; } } // token.parent is a variableDeclaration - function deleteVariableDeclaration(varDecl: ts.VariableDeclaration): CodeAction[] | undefined { + function deleteVariableDeclarationOrPrefixWithUnderscore(identifier: Identifier, varDecl: ts.VariableDeclaration): CodeAction[] | undefined { switch (varDecl.parent.parent.kind) { case SyntaxKind.ForStatement: const forStatement = varDecl.parent.parent; const forInitializer = forStatement.initializer; - if (forInitializer.declarations.length === 1) { - return deleteNode(forInitializer); - } - else { - return deleteNodeInList(varDecl); - } + return [forInitializer.declarations.length === 1 ? deleteNode(forInitializer) : deleteNodeInList(varDecl)]; case SyntaxKind.ForOfStatement: const forOfStatement = varDecl.parent.parent; Debug.assert(forOfStatement.initializer.kind === SyntaxKind.VariableDeclarationList); const forOfInitializer = forOfStatement.initializer; - return replaceNode(forOfInitializer.declarations[0], createObjectLiteral()); + return [ + replaceNode(forOfInitializer.declarations[0], createObjectLiteral()), + prefixIdentifierWithUnderscore(identifier) + ]; case SyntaxKind.ForInStatement: // There is no valid fix in the case of: // for .. in - return undefined; + return [prefixIdentifierWithUnderscore(identifier)]; default: const variableStatement = varDecl.parent.parent; if (variableStatement.declarationList.declarations.length === 1) { - return deleteNode(variableStatement); + return [deleteNode(variableStatement)]; } else { - return deleteNodeInList(varDecl); + return [deleteNodeInList(varDecl)]; } } } @@ -196,11 +190,11 @@ namespace ts.codefix { return makeChange(textChanges.ChangeTracker.fromCodeFixContext(context).replaceNode(sourceFile, n, newNode)); } - function makeChange(changeTracker: textChanges.ChangeTracker) { - return [{ + function makeChange(changeTracker: textChanges.ChangeTracker): CodeAction { + return { description: formatStringFromArgs(getLocaleSpecificMessage(Diagnostics.Remove_declaration_for_Colon_0), { 0: token.getText() }), changes: changeTracker.getChanges() - }]; + }; } } });