Skip to content

Commit

Permalink
fix(unused): Don't delete imports more than once.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed Mar 29, 2019
1 parent c92d07c commit a8b634d
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 2 deletions.
7 changes: 7 additions & 0 deletions fixtures/issues/15/example-1.ts.fix
@@ -0,0 +1,7 @@
import * as dotenv from "dotenv";
import * as Hapi from "hapi";
import * as path from "path";
dotenv.config({ path: path.join(__dirname, "../.env") });
import "./arrayIncludesShim";
const server = new Hapi.Server();

19 changes: 19 additions & 0 deletions fixtures/issues/15/example-1.ts.lint
@@ -0,0 +1,19 @@
import * as dotenv from "dotenv";
import * as Hapi from "hapi";
import * as path from "path";
dotenv.config({ path: path.join(__dirname, "../.env") });
import { ResetTemplateCache } from "./getTemplate";
~~~~~~~~~~~~~~~~~~ [no-unused-declaration]
import {
RequestMethod,
~~~~~~~~~~~~~ [no-unused-declaration]
sendAsanaRequest,
~~~~~~~~~~~~~~~~ [no-unused-declaration]
} from "./sendAsanaRequest";
import "./arrayIncludesShim";
import { startAsanaTimer } from "./startAsanaTimer";
~~~~~~~~~~~~~~~ [no-unused-declaration]
const server = new Hapi.Server();
~~~~~~ [no-unused-declaration]

[no-unused-declaration]: Unused declarations are forbidden
7 changes: 7 additions & 0 deletions fixtures/issues/15/example-2.ts.fix
@@ -0,0 +1,7 @@
import * as dotenv from "dotenv";
import * as Hapi from "hapi";
import * as path from "path";
dotenv.config({ path: path.join(__dirname, "../.env") });
import "./arrayIncludesShim";
const server = new Hapi.Server();

23 changes: 23 additions & 0 deletions fixtures/issues/15/example-2.ts.lint
@@ -0,0 +1,23 @@
import * as dotenv from "dotenv";
import * as Hapi from "hapi";
import * as path from "path";
dotenv.config({ path: path.join(__dirname, "../.env") });
import {
ResetTemplateCache,
~~~~~~~~~~~~~~~~~~ [no-unused-declaration]
} from "./getTemplate";
import {
hasActiveRequest,
~~~~~~~~~~~~~~~~ [no-unused-declaration]
RequestMethod,
~~~~~~~~~~~~~ [no-unused-declaration]
sendAsanaRequest,
~~~~~~~~~~~~~~~~ [no-unused-declaration]
} from "./sendAsanaRequest";
import "./arrayIncludesShim";
import { startAsanaTimer } from "./startAsanaTimer";
~~~~~~~~~~~~~~~ [no-unused-declaration]
const server = new Hapi.Server();
~~~~~~ [no-unused-declaration]

[no-unused-declaration]: Unused declarations are forbidden
8 changes: 8 additions & 0 deletions fixtures/issues/15/example-3.ts.fix
@@ -0,0 +1,8 @@
import * as dotenv from "dotenv";
import * as Hapi from "hapi";
import * as path from "path";
dotenv.config({ path: path.join(__dirname, "../.env") });
// Just import the module to run the code inside and create global Array shim
import "./arrayIncludesShim";
const server = new Hapi.Server();

20 changes: 20 additions & 0 deletions fixtures/issues/15/example-3.ts.lint
@@ -0,0 +1,20 @@
import * as dotenv from "dotenv";
import * as Hapi from "hapi";
import * as path from "path";
dotenv.config({ path: path.join(__dirname, "../.env") });
import { ResetTemplateCache } from "./getTemplate";
~~~~~~~~~~~~~~~~~~ [no-unused-declaration]
import {
RequestMethod,
~~~~~~~~~~~~~ [no-unused-declaration]
sendAsanaRequest,
~~~~~~~~~~~~~~~~ [no-unused-declaration]
} from "./sendAsanaRequest";
// Just import the module to run the code inside and create global Array shim
import "./arrayIncludesShim";
import { startAsanaTimer } from "./startAsanaTimer";
~~~~~~~~~~~~~~~ [no-unused-declaration]
const server = new Hapi.Server();
~~~~~~ [no-unused-declaration]

[no-unused-declaration]: Unused declarations are forbidden
5 changes: 5 additions & 0 deletions fixtures/issues/15/tsconfig.json
@@ -0,0 +1,5 @@
{
"compilerOptions": {
"module": "commonjs"
}
}
8 changes: 8 additions & 0 deletions fixtures/issues/15/tslint.json
@@ -0,0 +1,8 @@
{
"defaultSeverity": "error",
"jsRules": {},
"rules": {
"no-unused-declaration": { "severity": "error" }
},
"rulesDirectory": "../../../build/rules"
}
3 changes: 3 additions & 0 deletions fixtures/no-unused-declaration/unused-imports/fixture.ts.fix
@@ -1,4 +1,7 @@

import { b } from "./letters";
import { b as basil } from "./letters";

console.log(b, basil);
console.log("the end");

14 changes: 13 additions & 1 deletion fixtures/no-unused-declaration/unused-imports/fixture.ts.lint
@@ -1,12 +1,24 @@
import { a } from "./letters";
~ [no-unused-declaration]
import { a as alias } from "./letters";
import { b } from "./letters";
import { c, d } from "./letters";
~ [no-unused-declaration]
~ [no-unused-declaration]
import { a as anise } from "./letters";
~~~~~ [no-unused-declaration]
import { b as basil } from "./letters";
import {
c as carrot,
~~~~~~ [no-unused-declaration]
d as dill
~~~~ [no-unused-declaration]
} from "./letters";
import * as l from "./letters";
~ [no-unused-declaration]
import letters from "./letters";
~~~~~~~ [no-unused-declaration]

console.log(b, basil);
console.log("the end");

[no-unused-declaration]: Unused declarations are forbidden
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -47,7 +47,7 @@
"test": "yarn run lint && yarn run test:build && yarn run test:tslint",
"test:build": "yarn run test:clean && tsc -p tsconfig.json",
"test:clean": "rimraf build",
"test:debug": "tslint --test fixtures/no-unused-declaration/used-destructuring/tslint.json",
"test:debug": "tslint --test fixtures/no-unused-declaration/unused-imports/tslint.json",
"test:tslint": "tslint --test fixtures/**/tslint.json"
},
"version": "1.4.3"
Expand Down
8 changes: 8 additions & 0 deletions source/rules/noUnusedDeclarationRule.ts
Expand Up @@ -41,6 +41,7 @@ export class Walker extends Lint.ProgramAwareRuleWalker {

private _associationsByIdentifier = new Map<ts.Node, ts.Node[]>();
private _declarationsByIdentifier = new Map<ts.Node, ts.Node>();
private _deletes = new Set<ts.Node>();
private _scopes = [new Map<string, ts.Identifier>()];
private _withoutDeclarations = new Set<string>();
private _usageByIdentifier = new Map<ts.Node, "declared" | "seen" | "used">();
Expand Down Expand Up @@ -258,7 +259,9 @@ export class Walker extends Lint.ProgramAwareRuleWalker {

private getFix(identifier: ts.Node, declaration: ts.Node): Lint.Fix | undefined {

const { _deletes } = this;
if (tsutils.isImportDeclaration(declaration)) {
_deletes.add(declaration);
return Lint.Replacement.deleteFromTo(
declaration.getFullStart(),
declaration.getFullStart() + declaration.getFullWidth()
Expand All @@ -269,6 +272,10 @@ export class Walker extends Lint.ProgramAwareRuleWalker {
if (elements.every(element => _usageByIdentifier.get(element.name) === "declared")) {
const importClause = declaration.parent as ts.ImportClause;
const importDeclaration = importClause.parent as ts.ImportDeclaration;
if (_deletes.has(importDeclaration)) {
return undefined;
}
_deletes.add(importDeclaration);
return Lint.Replacement.deleteFromTo(
importDeclaration.getFullStart(),
importDeclaration.getFullStart() + importDeclaration.getFullWidth()
Expand All @@ -285,6 +292,7 @@ export class Walker extends Lint.ProgramAwareRuleWalker {
} else if (tsutils.isNamespaceImport(declaration)) {
const importClause = declaration.parent as ts.ImportClause;
const importDeclaration = importClause.parent as ts.ImportDeclaration;
_deletes.add(importDeclaration);
return Lint.Replacement.deleteFromTo(
importDeclaration.getFullStart(),
importDeclaration.getFullStart() + importDeclaration.getFullWidth()
Expand Down

0 comments on commit a8b634d

Please sign in to comment.