Skip to content

Commit

Permalink
refactor: handle removing one of multiple import specifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
mshanemc committed Dec 13, 2023
1 parent 4480486 commit ad0b52a
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 23 deletions.
60 changes: 37 additions & 23 deletions src/rules/esm-message-import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,34 +46,48 @@ export const esmMessageImport = RuleCreator.withoutDocs({
}
},
ImportDeclaration(node): void {
const allCode = context.getSourceCode().getText();
// true for all cases
if (
node.specifiers.length === 1 &&
node.specifiers[0].type === AST_NODE_TYPES.ImportSpecifier &&
node.specifiers[0].local.type === AST_NODE_TYPES.Identifier &&
((node.source.value === 'node:url' &&
node.specifiers[0].local.name === 'fileURLToPath' &&
Array.from(
context
.getSourceCode()
.getText()
.matchAll(/fileURLToPath/g)
).length === 1) ||
node.specifiers.some((s) => s.local.name === 'fileURLToPath') &&
// it's the only reference to fileURLToPath
Array.from(allCode.matchAll(/fileURLToPath/g)).length === 1) ||
(node.source.value === 'node:path' &&
node.specifiers[0].local.name === 'dirname' &&
Array.from(
context
.getSourceCode()
.getText()
.matchAll(/dirname/g)
).length === 1)) &&
node.specifiers.some((s) => s.local.name === 'dirname') &&
// it's the only reference to dirname
Array.from(allCode.matchAll(/dirname/g)).length === 1)) &&
// we've already removed the old way of doing it
context.getSourceCode().getText().includes('Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)')
allCode.includes('Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)')
) {
return context.report({
node,
messageId: 'unnecessaryImport',
fix: (fixer) => fixer.remove(node),
});
if (
// case 1: single specifier removes the entire import line
node.specifiers.length === 1 &&
node.specifiers[0].type === AST_NODE_TYPES.ImportSpecifier &&
node.specifiers[0].local.type === AST_NODE_TYPES.Identifier
) {
return context.report({
node,
messageId: 'unnecessaryImport',
fix: (fixer) => fixer.remove(node),
});
} else {
if (node.specifiers.length > 1) {
const replacementSpecifiers = node.specifiers
.filter((s) => s.local.name !== 'dirname' && s.local.name !== 'fileURLToPath')
.map((s) => s.local.name)
.join(', ');
const replacementRange = [
node.specifiers[0].range[0],
node.specifiers[node.specifiers.length - 1].range[1],
] as const;
return context.report({
node,
messageId: 'unnecessaryImport',
fix: (fixer) => fixer.replaceTextRange(replacementRange, replacementSpecifiers),
});
}
}
}
},
// now we're going to clean up unused imports if they're left over
Expand Down
56 changes: 56 additions & 0 deletions test/rules/esm-message-imports.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ import { fileURLToPath } from 'node:url';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)
const foo = dirname('foo/bar')
const foo = fileURLToPath('file:///foo/bar')
`,
},
{
name: 'destructured imports used by other code',
code: `
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)
const foo = dirname('foo/bar')
const foo = fileURLToPath('file:///foo/bar')
`,
Expand Down Expand Up @@ -81,6 +93,50 @@ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)
output: `
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)
`,
},
{
name: 'new loader with extra imports removes only the dirname import (when not last)',
errors: [
{
messageId: 'unnecessaryImport',
},
{
messageId: 'unnecessaryImport',
},
],
code: `
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)
`,
// other code (ex: prettier) can handle the extra whitespaces
output: `
import { join } from 'node:path'
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)
`,
},
{
name: 'new loader with extra imports removes only the dirname import (when last)',
errors: [
{
messageId: 'unnecessaryImport',
},
{
messageId: 'unnecessaryImport',
},
],
code: `
import { join, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)
`,
// other code (ex: prettier) can handle the extra whitespaces
output: `
import { join } from 'node:path'
Messages.importMessagesDirectoryFromMetaUrl(import.meta.url)
`,
},
Expand Down

0 comments on commit ad0b52a

Please sign in to comment.