Skip to content

Commit 6250dab

Browse files
chore: enabled eslint-plugin-perfectionist on utils (typescript-eslint#9698)
* chore: enabled eslint-plugin-perfectionist on utils * Set ignoreCase to false * Apply suggestions from code review Co-authored-by: Brad Zacher <brad.zacher@gmail.com> * Put nullish last * Remove ignoreCase * Bump to version with fixed types --------- Co-authored-by: Brad Zacher <brad.zacher@gmail.com>
1 parent a38819c commit 6250dab

25 files changed

+430
-334
lines changed

eslint.config.mjs

+32
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import importPlugin from 'eslint-plugin-import';
1313
import jestPlugin from 'eslint-plugin-jest';
1414
import jsdocPlugin from 'eslint-plugin-jsdoc';
1515
import jsxA11yPlugin from 'eslint-plugin-jsx-a11y';
16+
import perfectionistPlugin from 'eslint-plugin-perfectionist';
1617
import reactPlugin from 'eslint-plugin-react';
1718
import reactHooksPlugin from 'eslint-plugin-react-hooks';
1819
import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
@@ -575,4 +576,35 @@ export default tseslint.config(
575576
'import/no-default-export': 'off',
576577
},
577578
},
579+
{
580+
extends: [perfectionistPlugin.configs['recommended-alphabetical']],
581+
files: ['packages/utils/src/**/*.ts'],
582+
rules: {
583+
'perfectionist/sort-classes': [
584+
'error',
585+
{
586+
order: 'asc',
587+
partitionByComment: true,
588+
type: 'natural',
589+
},
590+
],
591+
'perfectionist/sort-objects': [
592+
'error',
593+
{
594+
order: 'asc',
595+
partitionByComment: true,
596+
type: 'natural',
597+
},
598+
],
599+
'perfectionist/sort-union-types': [
600+
'error',
601+
{
602+
order: 'asc',
603+
groups: ['unknown', 'keyword', 'nullish'],
604+
type: 'natural',
605+
},
606+
],
607+
'simple-import-sort/imports': 'off',
608+
},
609+
},
578610
);

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
"eslint-plugin-jest": "^27.9.0",
101101
"eslint-plugin-jsdoc": "^47.0.2",
102102
"eslint-plugin-jsx-a11y": "^6.8.0",
103+
"eslint-plugin-perfectionist": "^3.2.0",
103104
"eslint-plugin-react": "^7.34.1",
104105
"eslint-plugin-react-hooks": "^4.6.0",
105106
"eslint-plugin-simple-import-sort": "^10.0.0",

packages/utils/src/ast-utils/eslint-utils/PatternMatcher.ts

+15-15
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
11
import * as eslintUtils from '@eslint-community/eslint-utils';
22

33
interface PatternMatcher {
4-
/**
5-
* Iterate all matched parts in a given string.
6-
*
7-
* @see {@link https://eslint-community.github.io/eslint-utils/api/ast-utils.html#matcher-execall}
8-
*/
9-
execAll(str: string): IterableIterator<RegExpExecArray>;
10-
11-
/**
12-
* Check whether this pattern matches a given string or not.
13-
*
14-
* @see {@link https://eslint-community.github.io/eslint-utils/api/ast-utils.html#matcher-test}
15-
*/
16-
test(str: string): boolean;
17-
184
/**
195
* Replace all matched parts by a given replacer.
206
*
@@ -39,8 +25,22 @@ interface PatternMatcher {
3925
*/
4026
[Symbol.replace](
4127
str: string,
42-
replacer: string | ((...strs: string[]) => string),
28+
replacer: ((...strs: string[]) => string) | string,
4329
): string;
30+
31+
/**
32+
* Iterate all matched parts in a given string.
33+
*
34+
* @see {@link https://eslint-community.github.io/eslint-utils/api/ast-utils.html#matcher-execall}
35+
*/
36+
execAll(str: string): IterableIterator<RegExpExecArray>;
37+
38+
/**
39+
* Check whether this pattern matches a given string or not.
40+
*
41+
* @see {@link https://eslint-community.github.io/eslint-utils/api/ast-utils.html#matcher-test}
42+
*/
43+
test(str: string): boolean;
4444
}
4545

4646
/**

packages/utils/src/ast-utils/eslint-utils/ReferenceTracker.ts

+20-19
Original file line numberDiff line numberDiff line change
@@ -13,55 +13,56 @@ const ReferenceTrackerESM: unique symbol = eslintUtils.ReferenceTracker.ESM;
1313
interface ReferenceTracker {
1414
/**
1515
* Iterate the references that the given `traceMap` determined.
16-
* This method starts to search from global variables.
16+
* This method starts to search from `require()` expression.
1717
*
18-
* @see {@link https://eslint-community.github.io/eslint-utils/api/scope-utils.html#tracker-iterateglobalreferences}
18+
* @see {@link https://eslint-community.github.io/eslint-utils/api/scope-utils.html#tracker-iteratecjsreferences}
1919
*/
20-
iterateGlobalReferences<T>(
20+
iterateCjsReferences<T>(
2121
traceMap: ReferenceTracker.TraceMap<T>,
2222
): IterableIterator<ReferenceTracker.FoundReference<T>>;
2323

2424
/**
2525
* Iterate the references that the given `traceMap` determined.
26-
* This method starts to search from `require()` expression.
26+
* This method starts to search from `import`/`export` declarations.
2727
*
28-
* @see {@link https://eslint-community.github.io/eslint-utils/api/scope-utils.html#tracker-iteratecjsreferences}
28+
* @see {@link https://eslint-community.github.io/eslint-utils/api/scope-utils.html#tracker-iterateesmreferences}
2929
*/
30-
iterateCjsReferences<T>(
30+
iterateEsmReferences<T>(
3131
traceMap: ReferenceTracker.TraceMap<T>,
3232
): IterableIterator<ReferenceTracker.FoundReference<T>>;
3333

3434
/**
3535
* Iterate the references that the given `traceMap` determined.
36-
* This method starts to search from `import`/`export` declarations.
36+
* This method starts to search from global variables.
3737
*
38-
* @see {@link https://eslint-community.github.io/eslint-utils/api/scope-utils.html#tracker-iterateesmreferences}
38+
* @see {@link https://eslint-community.github.io/eslint-utils/api/scope-utils.html#tracker-iterateglobalreferences}
3939
*/
40-
iterateEsmReferences<T>(
40+
iterateGlobalReferences<T>(
4141
traceMap: ReferenceTracker.TraceMap<T>,
4242
): IterableIterator<ReferenceTracker.FoundReference<T>>;
4343
}
4444
interface ReferenceTrackerStatic {
45+
readonly CALL: typeof ReferenceTrackerCALL;
46+
readonly CONSTRUCT: typeof ReferenceTrackerCONSTRUCT;
47+
readonly ESM: typeof ReferenceTrackerESM;
48+
4549
new (
4650
globalScope: TSESLint.Scope.Scope,
4751
options?: {
52+
/**
53+
* The name list of Global Object. Optional. Default is `["global", "globalThis", "self", "window"]`.
54+
*/
55+
globalObjectNames?: readonly string[];
4856
/**
4957
* The mode which determines how the `tracker.iterateEsmReferences()` method scans CommonJS modules.
5058
* If this is `"strict"`, the method binds CommonJS modules to the default export. Otherwise, the method binds
5159
* CommonJS modules to both the default export and named exports. Optional. Default is `"strict"`.
5260
*/
5361
mode?: 'legacy' | 'strict';
54-
/**
55-
* The name list of Global Object. Optional. Default is `["global", "globalThis", "self", "window"]`.
56-
*/
57-
globalObjectNames?: readonly string[];
5862
},
5963
): ReferenceTracker;
6064

6165
readonly READ: typeof ReferenceTrackerREAD;
62-
readonly CALL: typeof ReferenceTrackerCALL;
63-
readonly CONSTRUCT: typeof ReferenceTrackerCONSTRUCT;
64-
readonly ESM: typeof ReferenceTrackerESM;
6566
}
6667

6768
namespace ReferenceTracker {
@@ -73,18 +74,18 @@ namespace ReferenceTracker {
7374
// eslint-disable-next-line @typescript-eslint/no-explicit-any
7475
export type TraceMap<T = any> = Record<string, TraceMapElement<T>>;
7576
export interface TraceMapElement<T> {
76-
[ReferenceTrackerREAD]?: T;
77+
[key: string]: TraceMapElement<T>;
7778
[ReferenceTrackerCALL]?: T;
7879
[ReferenceTrackerCONSTRUCT]?: T;
7980
[ReferenceTrackerESM]?: true;
80-
[key: string]: TraceMapElement<T>;
81+
[ReferenceTrackerREAD]?: T;
8182
}
8283
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8384
export interface FoundReference<T = any> {
85+
info: T;
8486
node: TSESTree.Node;
8587
path: readonly string[];
8688
type: ReferenceType;
87-
info: T;
8889
}
8990
}
9091

packages/utils/src/ast-utils/eslint-utils/astUtilities.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,12 @@ const hasSideEffect = eslintUtils.hasSideEffect as (
105105
) => boolean;
106106

107107
const isParenthesized = eslintUtils.isParenthesized as {
108+
(
109+
times: number,
110+
node: TSESTree.Node,
111+
sourceCode: TSESLint.SourceCode,
112+
): boolean;
113+
108114
/**
109115
* Check whether a given node is parenthesized or not.
110116
* This function detects it correctly even if it's parenthesized by specific syntax.
@@ -115,11 +121,6 @@ const isParenthesized = eslintUtils.isParenthesized as {
115121
* For example, `isParenthesized(2, node, sourceCode)` returns true for `((foo))`, but not for `(foo)`.
116122
*/
117123
(node: TSESTree.Node, sourceCode: TSESLint.SourceCode): boolean;
118-
(
119-
times: number,
120-
node: TSESTree.Node,
121-
sourceCode: TSESLint.SourceCode,
122-
): boolean;
123124
};
124125

125126
export {

packages/utils/src/ast-utils/eslint-utils/predicates.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ type IsNotSpecificTokenFunction<SpecificToken extends TSESTree.Token> = (
1010
token: TSESTree.Token,
1111
) => token is Exclude<TSESTree.Token, SpecificToken>;
1212

13-
type PunctuatorTokenWithValue<Value extends string> =
14-
TSESTree.PunctuatorToken & { value: Value };
13+
type PunctuatorTokenWithValue<Value extends string> = {
14+
value: Value;
15+
} & TSESTree.PunctuatorToken;
1516
type IsPunctuatorTokenWithValueFunction<Value extends string> =
1617
IsSpecificTokenFunction<PunctuatorTokenWithValue<Value>>;
1718
type IsNotPunctuatorTokenWithValueFunction<Value extends string> =

packages/utils/src/ast-utils/helpers.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ export const isTokenOfTypeWithConditions = <
4343
// This is technically unsafe, but we find it useful to extract out the type
4444
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
4545
ExtractedToken extends Extract<TSESTree.Token, { type: TokenType }>,
46-
Conditions extends Partial<TSESTree.Token & { type: TokenType }>,
46+
Conditions extends Partial<{ type: TokenType } & TSESTree.Token>,
4747
>(
4848
tokenType: TokenType,
4949
conditions: Conditions,

packages/utils/src/ast-utils/predicates.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { TSESTree } from '../ts-estree';
2+
23
import { AST_NODE_TYPES, AST_TOKEN_TYPES } from '../ts-estree';
34
import {
45
isNodeOfType,
@@ -164,20 +165,20 @@ const isLoop = isNodeOfTypes([
164165
export {
165166
isAwaitExpression,
166167
isAwaitKeyword,
167-
isConstructor,
168168
isClassOrTypeElement,
169+
isConstructor,
169170
isFunction,
170171
isFunctionOrFunctionType,
171172
isFunctionType,
172173
isIdentifier,
173174
isImportKeyword,
174-
isLoop,
175175
isLogicalOrOperator,
176+
isLoop,
176177
isNonNullAssertionPunctuator,
177178
isNotNonNullAssertionPunctuator,
178179
isNotOptionalChainPunctuator,
179-
isOptionalChainPunctuator,
180180
isOptionalCallExpression,
181+
isOptionalChainPunctuator,
181182
isSetter,
182183
isTSConstructorType,
183184
isTSFunctionType,

packages/utils/src/eslint-utils/InferTypesFromRule.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ type InferMessageIdsTypeFromRule<T> =
2020
? MessageIds
2121
: unknown;
2222

23-
export { InferOptionsTypeFromRule, InferMessageIdsTypeFromRule };
23+
export { InferMessageIdsTypeFromRule, InferOptionsTypeFromRule };

packages/utils/src/eslint-utils/RuleCreator.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import type {
55
RuleMetaDataDocs,
66
RuleModule,
77
} from '../ts-eslint/Rule';
8+
89
import { applyDefault } from './applyDefault';
910

1011
export type { RuleListener, RuleModule };
@@ -15,9 +16,9 @@ export type NamedCreateRuleMetaDocs = Omit<RuleMetaDataDocs, 'url'>;
1516
export type NamedCreateRuleMeta<
1617
MessageIds extends string,
1718
PluginDocs = unknown,
18-
> = Omit<RuleMetaData<MessageIds, PluginDocs>, 'docs'> & {
19-
docs: RuleMetaDataDocs & PluginDocs;
20-
};
19+
> = {
20+
docs: PluginDocs & RuleMetaDataDocs;
21+
} & Omit<RuleMetaData<MessageIds, PluginDocs>, 'docs'>;
2122

2223
export interface RuleCreateAndOptions<
2324
Options extends readonly unknown[],
@@ -62,8 +63,8 @@ export function RuleCreator<PluginDocs = unknown>(
6263
Options extends readonly unknown[],
6364
MessageIds extends string,
6465
>({
65-
name,
6666
meta,
67+
name,
6768
...rule
6869
}: Readonly<
6970
RuleWithMetaAndName<Options, MessageIds, PluginDocs>

packages/utils/src/eslint-utils/getParserServices.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
ParserServices,
44
ParserServicesWithTypeInformation,
55
} from '../ts-estree';
6+
67
import { parserSeemsToBeTSESLint } from './parserSeemsToBeTSESLint';
78

89
const ERROR_MESSAGE_REQUIRES_PARSER_SERVICES =
+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export * from './applyDefault';
2+
export * from './deepMerge';
23
export * from './getParserServices';
34
export * from './InferTypesFromRule';
4-
export * from './RuleCreator';
5-
export * from './deepMerge';
65
export * from './nullThrows';
6+
export * from './RuleCreator';

0 commit comments

Comments
 (0)