Skip to content

Commit de896f4

Browse files
authored
refactor: migrate several rules (#50)
1 parent 3d7a551 commit de896f4

28 files changed

+1316
-1183
lines changed

.changeset/odd-chicken-boil.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"eslint-plugin-import-x": patch
3+
---
4+
5+
refactor: migrate several rules
Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,37 @@
11
diff --git a/node_modules/@typescript-eslint/utils/dist/ts-eslint/Rule.d.ts b/node_modules/@typescript-eslint/utils/dist/ts-eslint/Rule.d.ts
2-
index 9a3a1fd..6a2e2dd 100644
2+
index 9a3a1fd..c6ed412 100644
33
--- a/node_modules/@typescript-eslint/utils/dist/ts-eslint/Rule.d.ts
44
+++ b/node_modules/@typescript-eslint/utils/dist/ts-eslint/Rule.d.ts
5-
@@ -7,15 +7,13 @@ import type { SourceCode } from './SourceCode';
5+
@@ -6,6 +6,10 @@ import type { Scope } from './Scope';
6+
import type { SourceCode } from './SourceCode';
67
export type RuleRecommendation = 'error' | 'strict' | 'warn' | false;
78
interface RuleMetaDataDocs {
8-
/**
9-
- * Concise description of the rule
9+
+ /**
1010
+ * The category the rule falls under
11-
*/
12-
- description: string;
11+
+ */
1312
+ category?: string;
1413
/**
15-
- * The recommendation level for the rule.
16-
- * Used by the build tools to generate the recommended and strict configs.
17-
- * Set to false to not include it as a recommendation
18-
+ * Concise description of the rule
14+
* Concise description of the rule
15+
*/
16+
@@ -15,7 +19,7 @@ interface RuleMetaDataDocs {
17+
* Used by the build tools to generate the recommended and strict configs.
18+
* Set to false to not include it as a recommendation
1919
*/
2020
- recommended: 'error' | 'strict' | 'warn' | false;
21-
+ description: string;
21+
+ recommended?: 'error' | 'strict' | 'warn' | boolean;
2222
/**
2323
* The URL of the rule's docs
2424
*/
25+
diff --git a/node_modules/@typescript-eslint/utils/dist/ts-eslint/RuleTester.d.ts b/node_modules/@typescript-eslint/utils/dist/ts-eslint/RuleTester.d.ts
26+
index c8afefe..d629d04 100644
27+
--- a/node_modules/@typescript-eslint/utils/dist/ts-eslint/RuleTester.d.ts
28+
+++ b/node_modules/@typescript-eslint/utils/dist/ts-eslint/RuleTester.d.ts
29+
@@ -115,7 +115,7 @@ interface RunTests<TMessageIds extends string, TOptions extends Readonly<unknown
30+
readonly invalid: readonly InvalidTestCase<TMessageIds, TOptions>[];
31+
}
32+
interface RuleTesterConfig extends Linter.Config {
33+
- readonly parser: string;
34+
+ readonly parser?: string;
35+
readonly parserOptions?: Readonly<ParserOptions>;
36+
}
37+
declare class RuleTesterBase {

src/export-map.ts

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ export interface DeclarationMetadata {
4444
isOnlyImportingTypes?: boolean
4545
}
4646

47+
export interface ModuleNamespace {
48+
doc?: Annotation
49+
namespace?: ExportMap | null
50+
}
51+
52+
export interface ModuleImport {
53+
getter: () => ExportMap | null
54+
declarations: Set<DeclarationMetadata>
55+
}
56+
4757
export class ExportMap {
4858
static for(context: ChildContext) {
4959
const { path } = context
@@ -216,18 +226,25 @@ export class ExportMap {
216226
return ExportMap.for(childContext(rp, context))
217227
}
218228

219-
function getNamespace(identifier: TSESTree.Identifier) {
220-
if (!namespaces.has(identifier.name)) {
229+
function getNamespace(identifier: TSESTree.Identifier | string) {
230+
const namespace =
231+
typeof identifier === 'string' ? identifier : identifier.name
232+
if (!namespaces.has(namespace)) {
221233
return
222234
}
223235

224236
return function () {
225-
return resolveImport(namespaces.get(identifier.name))
237+
return resolveImport(namespaces.get(namespace))
226238
}
227239
}
228240

229-
function addNamespace(object: object, identifier: TSESTree.Identifier) {
230-
const nsfn = getNamespace(identifier)
241+
function addNamespace(
242+
object: object,
243+
identifier: TSESTree.Identifier | string,
244+
) {
245+
const namespace =
246+
typeof identifier === 'string' ? identifier : identifier.name
247+
const nsfn = getNamespace(namespace)
231248
if (nsfn) {
232249
Object.defineProperty(object, 'namespace', { get: nsfn })
233250
}
@@ -247,7 +264,7 @@ export class ExportMap {
247264
n.source &&
248265
(n.source as TSESTree.StringLiteral).value) as string
249266

250-
const exportMeta = {}
267+
const exportMeta: ModuleNamespace = {}
251268

252269
let local: string
253270

@@ -273,11 +290,7 @@ export class ExportMap {
273290
s.exported!.name ||
274291
// @ts-expect-error - legacy parser type
275292
s.exported!.value,
276-
addNamespace(
277-
exportMeta,
278-
// @ts-expect-error -- FIXME: no idea yet
279-
s.source.value,
280-
),
293+
addNamespace(exportMeta, s.source.value),
281294
)
282295
return
283296
case 'ExportSpecifier':
@@ -625,7 +638,7 @@ export class ExportMap {
625638
return m
626639
}
627640

628-
namespace = new Map()
641+
namespace = new Map<string, ModuleNamespace>()
629642

630643
// todo: restructure to key on path, value is resolver + map of names
631644
reexports = new Map<
@@ -644,19 +657,13 @@ export class ExportMap {
644657
/**
645658
* dependencies of this module that are not explicitly re-exported
646659
*/
647-
imports = new Map<
648-
string,
649-
{
650-
getter: () => ExportMap | null
651-
declarations: Set<DeclarationMetadata>
652-
}
653-
>()
660+
imports = new Map<string, ModuleImport>()
654661

655662
errors: ParseError[] = []
656663

657664
parseGoal: 'ambiguous' | 'Module' | 'Script' = 'ambiguous'
658665

659-
private declare visitorKeys: TSESLint.SourceCode.VisitorKeys | null
666+
declare visitorKeys: TSESLint.SourceCode.VisitorKeys | null
660667

661668
private declare mtime: Date
662669

@@ -770,7 +777,7 @@ export class ExportMap {
770777
return { found: false, path: [this] }
771778
}
772779

773-
get<T = unknown>(name: string): T | null | undefined {
780+
get(name: string): ModuleNamespace | null | undefined {
774781
if (this.namespace.has(name)) {
775782
return this.namespace.get(name)
776783
}
@@ -808,15 +815,15 @@ export class ExportMap {
808815

809816
const innerValue = innerMap.get(name)
810817
if (innerValue !== undefined) {
811-
return innerValue as T
818+
return innerValue
812819
}
813820
}
814821
}
815822
}
816823

817-
forEach<T>(
824+
forEach(
818825
callback: (
819-
value: T | null | undefined,
826+
value: ModuleNamespace | null | undefined,
820827
name: string,
821828
map: ExportMap,
822829
) => void,
@@ -839,7 +846,7 @@ export class ExportMap {
839846
return
840847
}
841848

842-
d.forEach<T>((v, n) => {
849+
d.forEach((v, n) => {
843850
if (n !== 'default') {
844851
callback.call(thisArg, v, n, this)
845852
}

src/index.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ import groupExports from './rules/group-exports'
1717
import noRelativePackages from './rules/no-relative-packages'
1818
import noRelativeParentImports from './rules/no-relative-parent-imports'
1919
import consistentTypeSpecifierStyle from './rules/consistent-type-specifier-style'
20+
import noSelfImport from './rules/no-self-import'
21+
import noCycle from './rules/no-cycle'
22+
import noNamedDefault from './rules/no-named-default'
23+
import noNamedAsDefault from './rules/no-named-as-default'
24+
import noNamedAsDefaultMember from './rules/no-named-as-default-member'
25+
import noAnonymousDefaultExport from './rules/no-anonymous-default-export'
26+
import noUnusedModules from './rules/no-unused-modules'
2027

2128
// configs
2229
import recommended from './config/recommended'
@@ -44,13 +51,13 @@ export const rules = {
4451
'no-relative-parent-imports': noRelativeParentImports,
4552
'consistent-type-specifier-style': consistentTypeSpecifierStyle,
4653

47-
'no-self-import': require('./rules/no-self-import'),
48-
'no-cycle': require('./rules/no-cycle'),
49-
'no-named-default': require('./rules/no-named-default'),
50-
'no-named-as-default': require('./rules/no-named-as-default'),
51-
'no-named-as-default-member': require('./rules/no-named-as-default-member'),
52-
'no-anonymous-default-export': require('./rules/no-anonymous-default-export'),
53-
'no-unused-modules': require('./rules/no-unused-modules'),
54+
'no-self-import': noSelfImport,
55+
'no-cycle': noCycle,
56+
'no-named-default': noNamedDefault,
57+
'no-named-as-default': noNamedAsDefault,
58+
'no-named-as-default-member': noNamedAsDefaultMember,
59+
'no-anonymous-default-export': noAnonymousDefaultExport,
60+
'no-unused-modules': noUnusedModules,
5461

5562
'no-commonjs': require('./rules/no-commonjs'),
5663
'no-amd': require('./rules/no-amd'),

src/rules/namespace.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type Options = {
1818

1919
function processBodyStatement(
2020
context: RuleContext<MessageId>,
21-
namespaces: Map<string, ExportMap>,
21+
namespaces: Map<string, ExportMap | null>,
2222
declaration: TSESTree.ProgramStatement,
2323
) {
2424
if (declaration.type !== 'ImportDeclaration') {
@@ -56,7 +56,7 @@ function processBodyStatement(
5656
break
5757
case 'ImportDefaultSpecifier':
5858
case 'ImportSpecifier': {
59-
const meta = imports.get<{ namespace?: ExportMap }>(
59+
const meta = imports.get(
6060
'imported' in specifier && specifier.imported
6161
? specifier.imported.name ||
6262
// @ts-expect-error - legacy parser node
@@ -136,7 +136,7 @@ export = createRule<[Options], MessageId>({
136136
// read options
137137
const { allowComputed } = context.options[0] || {}
138138

139-
const namespaces = new Map<string, ExportMap>()
139+
const namespaces = new Map<string, ExportMap | null>()
140140

141141
return {
142142
// pick up all imports at body entry time, to properly respect hoisting
@@ -231,9 +231,7 @@ export = createRule<[Options], MessageId>({
231231
break
232232
}
233233

234-
const exported = namespace.get<{ namespace: ExportMap }>(
235-
deref.property.name,
236-
)
234+
const exported = namespace.get(deref.property.name)
237235

238236
if (exported == null) {
239237
return
@@ -268,7 +266,7 @@ export = createRule<[Options], MessageId>({
268266
// DFS traverse child namespaces
269267
function testKey(
270268
pattern: TSESTree.Node,
271-
namespace?: ExportMap,
269+
namespace?: ExportMap | null,
272270
path: string[] = [initName],
273271
) {
274272
if (!(namespace instanceof ExportMap)) {
@@ -304,9 +302,7 @@ export = createRule<[Options], MessageId>({
304302

305303
path.push(property.key.name)
306304

307-
const dependencyExportMap = namespace.get<{ namespace: ExportMap }>(
308-
property.key.name,
309-
)
305+
const dependencyExportMap = namespace.get(property.key.name)
310306

311307
// could be null when ignored or ambiguous
312308
if (dependencyExportMap != null) {

src/rules/newline-after-import.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/**
2-
* @fileoverview Rule to enforce new line after import not followed by another import.
3-
* @author Radek Benkel
2+
* Rule to enforce new line after import not followed by another import.
43
*/
54

65
import { isStaticRequire } from '../core/static-require'
@@ -9,10 +8,6 @@ import { docsUrl } from '../docs-url'
98
import debug from 'debug'
109
const log = debug('eslint-plugin-import-x:rules:newline-after-import')
1110

12-
//------------------------------------------------------------------------------
13-
// Rule Definition
14-
//------------------------------------------------------------------------------
15-
1611
function containsNodeOrEqual(outerNode, innerNode) {
1712
return (
1813
outerNode.range[0] <= innerNode.range[0] &&

src/rules/no-amd.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,9 @@
11
/**
2-
* @fileoverview Rule to prefer imports to AMD
3-
* @author Jamund Ferguson
2+
* Rule to prefer imports to AMD
43
*/
54

65
import { docsUrl } from '../docs-url'
76

8-
//------------------------------------------------------------------------------
9-
// Rule Definition
10-
//------------------------------------------------------------------------------
11-
127
module.exports = {
138
meta: {
149
type: 'suggestion',

0 commit comments

Comments
 (0)