Skip to content

Commit

Permalink
Add no-unused-rule processing for imports
Browse files Browse the repository at this point in the history
  • Loading branch information
hildjj committed Feb 17, 2024
1 parent 3f31c42 commit 5bf5789
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 0 deletions.
39 changes: 39 additions & 0 deletions lib/rules/no-unused-rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,36 @@ const rule = {
},
messages: {
unused: "Rule '{{ name }}' is never used.",
unusedImport: "Library import '{{ name }}' is never used.",
},
schema: [],
},
create(context) {
const imports = new Map();
const rules = new Map();
const refs = new Set();
const importRefs = new Set();
return (0, utils_1.makeListener)({
import_binding(node) {
if (node.binding.id) {
imports.set(node.binding.id.value, node);
}
},
import_binding_all(node) {
if (node.binding.id) {
imports.set(node.binding.id.value, node);
}
},
import_binding_default(node) {
if (node.binding.id) {
imports.set(node.binding.id.value, node);
}
},
import_binding_rename(node) {
if (node.binding.id) {
imports.set(node.binding.id.value, node);
}
},
rule(node) {
if (rules.size === 0) {
// Default start rule counts as a reference.
Expand All @@ -28,9 +51,13 @@ const rule = {
rule_ref(node) {
refs.add(node.name.value);
},
library_ref(node) {
importRefs.add(node.library.value);
},
"Program:exit": () => {
for (const name of refs) {
rules.delete(name);
imports.delete(name);
}
for (const [name, r] of rules) {
context.report({
Expand All @@ -41,6 +68,18 @@ const rule = {
},
});
}
for (const name of importRefs) {
imports.delete(name);
}
for (const [name, r] of imports) {
context.report({
node: (0, utils_1.n)(r),
messageId: "unusedImport",
data: {
name,
},
});
}
},
});
},
Expand Down
44 changes: 44 additions & 0 deletions src/rules/no-unused-rules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,41 @@ const rule: Rule.RuleModule = {
},
messages: {
unused: "Rule '{{ name }}' is never used.",
unusedImport: "Library import '{{ name }}' is never used.",
},
schema: [],
},
create(context: Rule.RuleContext): Rule.RuleListener {
const imports = new Map<string,
| visitor.AST.ImportBinding
| visitor.AST.ImportBindingAll
| visitor.AST.ImportBindingDefault
| visitor.AST.ImportBindingRename
>();
const rules = new Map<string, visitor.AST.Rule>();
const refs = new Set<string>();
const importRefs = new Set<string>();
return makeListener({
import_binding(node: visitor.AST.ImportBinding): void {
if (node.binding.id) {
imports.set(node.binding.id.value, node);
}
},
import_binding_all(node: visitor.AST.ImportBindingAll): void {
if (node.binding.id) {
imports.set(node.binding.id.value, node);
}
},
import_binding_default(node: visitor.AST.ImportBindingDefault): void {
if (node.binding.id) {
imports.set(node.binding.id.value, node);
}
},
import_binding_rename(node: visitor.AST.ImportBindingRename) {
if (node.binding.id) {
imports.set(node.binding.id.value, node);
}
},
rule(node: visitor.AST.Rule): void {
if (rules.size === 0) {
// Default start rule counts as a reference.
Expand All @@ -29,9 +57,13 @@ const rule: Rule.RuleModule = {
rule_ref(node: visitor.AST.RuleReferenceExpression): void {
refs.add(node.name.value);
},
library_ref(node: visitor.AST.LibraryReferenceExpression): void {
importRefs.add(node.library.value);
},
"Program:exit": (): void => {
for (const name of refs) {
rules.delete(name);
imports.delete(name);
}
for (const [name, r] of rules) {
context.report({
Expand All @@ -42,6 +74,18 @@ const rule: Rule.RuleModule = {
},
});
}
for (const name of importRefs) {
imports.delete(name);
}
for (const [name, r] of imports) {
context.report({
node: n(r),
messageId: "unusedImport",
data: {
name,
},
});
}
},
});
},
Expand Down
55 changes: 55 additions & 0 deletions test/rules/no-unused-rules.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,66 @@ foo = bar
bar = "1"
`,
},
{
code: `
import * as bar from "bar"
foo = bar.foo`,
},
{
code: `
import bar from 'bar'
foo = bar`,
},
{
code: `
import {bar} from 'bar'
foo = bar`,
},
{
code: `
import {foo as bar} from 'bar'
foo = bar`,
},
{
code: `
import {"foo" as bar} from 'bar'
foo = bar`,
},
],
invalid: [
{
code: "foo = '1'\nbar = '2'",
errors: [{ messageId: "unused" }],
},
{
code: `
import * as bar from "bar"
foo = bart.foo`,
errors: [{ messageId: "unusedImport" }],
},
{
code: `
import bar from "bar"
foo = "1"`,
errors: [{ messageId: "unusedImport" }],
},
{
code: `
import {bar} from "bar"
foo = "1"`,
errors: [{ messageId: "unusedImport" }],
},
{
code: `
import {foo as bar} from "bar"
foo = "1"`,
errors: [{ messageId: "unusedImport" }],
},
{
code: `
import {"foo" as bar} from "bar"
foo = "1"`,
errors: [{ messageId: "unusedImport" }],
},
],
});

0 comments on commit 5bf5789

Please sign in to comment.