GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — Codefix for removing Unused Identifiers by paulvanbrenk · Pull Request #11546 · microsoft/TypeScript Conversation
|
| const start = context.span.start; | ||
| const token = getTokenAtPosition(sourceFile, start); | ||
|
|
||
| if (token.kind === ts.SyntaxKind.Identifier) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
please refactor this into a switch statement.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
done
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); | ||
| } | ||
|
|
||
| if (token.parent.kind === SyntaxKind.ImportEqualsDeclaration) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
what does this mean. this is import m = require("mod");, you want to remove the whole declaration, and not just the identifier.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Also, please add a test for this.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
This is import a = A
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Tests are here, changed this to remove the whole line.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
|
|
||
| if (token.kind === SyntaxKind.AsteriskToken && token.parent.kind === SyntaxKind.NamespaceImport) { | ||
| return createCodeFix("{}", token.parent.pos, token.parent.end - token.parent.pos); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
do not think this is correct either. you need to check if this is the only import for this module, remove it whole sale, if not, remove whole import declaration.
also please add tests for the deffrent combinations of import:
import * as ns from "mod"; import d from "mod" import {a, b} from "mod" // where both are unused import {a, b} from "mod" // where only one is unused import d, * as ns from "mod"; // where both are unused import d, * as ns from "mod"; // where one of them is unsued, but the other is import d, {a, b} from "mod"; // where one of a,b, or d is unused, but other are not import d, {a, b} from "mod"; // where both a and b are unused, but d is not import d, {a, b} from "mod"; // where only d is unsued import d, {a, b} from "mod"; // where all are unused import m = require("mod"); import m = n.a;
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Since the cases where more than 1 import are unused, will result in 2 errors, and 2 fixes; so those would be identical to the single unused import.
All other cases have test cases.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| //// [|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 |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
please add another test with private readonly and another one with private is not in the first position.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
added
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| 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); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
this is not removing the whole line? do you mean namedImports.parent? I think you need to handle all cases. i have listed them below, also please add tests for each combination.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
|
|
||
| if (token.parent.kind === SyntaxKind.TypeParameter) { | ||
| const typeParameters = (<ClassDeclaration>token.parent.parent).typeParameters; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
why ClassDeclaraton? that can be function, interface declaration, method, type alias, arrow function, etc.. please add tests for these.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Used DeclWIthTypeParam, tests were already there.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
|
|
||
| if (token.parent.kind === ts.SyntaxKind.Parameter) { | ||
| const functionDeclaration = <FunctionDeclaration>token.parent.parent; |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
this is the same logic as above, please merge these two branches.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
done
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| token.parent.kind === SyntaxKind.MethodDeclaration || | ||
| token.parent.kind === SyntaxKind.ModuleDeclaration || | ||
| token.parent.kind === SyntaxKind.PropertyDeclaration || | ||
| token.parent.kind === SyntaxKind.ArrowFunction) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
how can an arrowFunction have an identifier as a name?
consider changing this to:
if (isDeclaration(token.parent) && (<Declaration>parent).name === token) { return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); }
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Also please add handeling for computed properties with non-identifier names:
class C { private ["string"] (){} private [Symbol.Iterator]() {} }
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| else if (token.parent.parent.parent.kind === SyntaxKind.ForInStatement) { | ||
| const forInStatement = <ForInStatement>token.parent.parent.parent; | ||
| const initializer = <VariableDeclarationList>forInStatement.initializer; | ||
| return createCodeFix("{}", initializer.declarations[0].pos, initializer.declarations[0].end - initializer.declarations[0].pos); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
this is not valid for..in statement. we should switch it x to _x and add special casing for _x to be not show the error. alternatively do nothing here, which would be my recommendation.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Doing nothing, modified test to make sure.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
| else { | ||
| const variableStatement = <VariableStatement>token.parent.parent.parent; | ||
| if (variableStatement.declarationList.declarations.length === 1) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
consider sharing the logic here with the other list removal cases.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
done
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| if (token.parent.parent.parent.kind === SyntaxKind.ForStatement) { | ||
| const forStatement = <ForStatement>token.parent.parent.parent; | ||
| const initializer = <VariableDeclarationList>forStatement.initializer; | ||
| if (initializer.declarations.length === 1) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
consider merging this into a list removal logic for all of the cases below.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
done
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
what about binding patterns? can you add tests for these cases. both for parameters and variable declarations.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| token.parent.kind === SyntaxKind.MethodDeclaration || | ||
| token.parent.kind === SyntaxKind.ModuleDeclaration || | ||
| token.parent.kind === SyntaxKind.PropertyDeclaration || | ||
| token.parent.kind === SyntaxKind.ArrowFunction) { |
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Also please add handeling for computed properties with non-identifier names:
class C { private ["string"] (){} private [Symbol.Iterator]() {} }
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| //// x++; | ||
| ////} | ||
|
|
||
| verify.codeFixAtPosition("var x;", 6133); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
No error codes in fourslash tests
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| break; | ||
|
|
||
| case SyntaxKind.ForInStatement: | ||
| // There is no valid fix in the case of: |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
rename the variable to start with _.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Out of scope, will add for 2nd iteration of this fix
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
| } | ||
|
|
||
| case SyntaxKind.FunctionDeclaration: |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
namespace, type alais, and enum as well
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
i would move this to the default clause and use isDeclarationName
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
done
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| case SyntaxKind.ImportSpecifier: | ||
| const namedImports = <NamedImports>token.parent.parent; | ||
| const elements = namedImports.elements; | ||
| if (elements.length === 1) { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
if no other imports in this list we need to remove the whole module import.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
| break; | ||
|
|
||
| case SyntaxKind.PrivateKeyword: |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
When is this ever used?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
removed
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| const token = getTokenAtPosition(sourceFile, start); | ||
|
|
||
| switch (token.kind) { | ||
| case ts.SyntaxKind.Identifier: |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
binding patterns are not handled anywhere:
function f({a, b}) {}
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
outside of scope, I think we can do a better job when we add the change signature refactoring
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| const token = getTokenAtPosition(sourceFile, start); | ||
|
|
||
| switch (token.kind) { | ||
| case ts.SyntaxKind.Identifier: |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Also please add handeling for computed properties with non-identifier names:
class C { private ["string"] (){} private [Symbol.Iterator]() {} }
Sorry, something went wrong.
There was an error while loading. Please reload this page.
|
|
||
| // @noUnusedLocals: true | ||
| // @Filename: file2.ts | ||
| //// [| import f1, * as s from "./file1"; |] |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Please add a test with both unused.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
That generates 2 errors and 2 fixes. So not applicable
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| case SyntaxKind.PropertyDeclaration: | ||
| return createCodeFix("", token.parent.pos, token.parent.end - token.parent.pos); | ||
|
|
||
| case SyntaxKind.AsteriskToken: |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
when do we get a * token?
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
removed
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
There was an error while loading. Please reload this page.