@eslint-react/core 5.2.1-next.3 → 5.2.2-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +43 -44
- package/dist/index.js +29 -30
- package/package.json +8 -8
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { TSESTreeClass, TSESTreeDirective, TSESTreeFunction } from "@eslint-react/ast";
|
|
1
|
+
import { ClassExpression, Directive, FunctionExpression, MethodOrPropertyDefinition } from "@eslint-react/ast";
|
|
3
2
|
import { TSESTree } from "@typescript-eslint/types";
|
|
4
3
|
import { RuleContext } from "@eslint-react/eslint";
|
|
5
4
|
import { RegExpLike } from "@eslint-react/shared";
|
|
@@ -119,7 +118,7 @@ declare const isUseTransitionCall: isAPICall.ReturnType;
|
|
|
119
118
|
* @param node The class node to get the identifier from
|
|
120
119
|
* @returns The class identifier or null if not found
|
|
121
120
|
*/
|
|
122
|
-
declare function getClassId(node:
|
|
121
|
+
declare function getClassId(node: ClassExpression): TSESTree.BindingName | null;
|
|
123
122
|
//#endregion
|
|
124
123
|
//#region src/semantic.d.ts
|
|
125
124
|
/**
|
|
@@ -150,7 +149,7 @@ interface SemanticFunc extends SemanticNode {
|
|
|
150
149
|
/** The identifier of the function */
|
|
151
150
|
id: null | TSESTree.Node;
|
|
152
151
|
/** The AST node of the function */
|
|
153
|
-
node:
|
|
152
|
+
node: FunctionExpression;
|
|
154
153
|
/** The name of the function */
|
|
155
154
|
name: string | null;
|
|
156
155
|
/** The return type annotation of the function */
|
|
@@ -158,7 +157,7 @@ interface SemanticFunc extends SemanticNode {
|
|
|
158
157
|
/** The body of the function */
|
|
159
158
|
body: TSESTree.BlockStatement | TSESTree.Expression;
|
|
160
159
|
/** The directives of the function (ex: "use strict", "use client", "use server", etc.) */
|
|
161
|
-
directives:
|
|
160
|
+
directives: Directive[];
|
|
162
161
|
/** The parameters of the function */
|
|
163
162
|
parameters: TSESTree.Parameter[];
|
|
164
163
|
/** The type parameters of the function */
|
|
@@ -175,68 +174,68 @@ interface ClassComponentSemanticNode extends SemanticNode {
|
|
|
175
174
|
displayName: null | TSESTree.Expression;
|
|
176
175
|
flag: bigint;
|
|
177
176
|
hint: bigint;
|
|
178
|
-
methods:
|
|
179
|
-
node:
|
|
177
|
+
methods: MethodOrPropertyDefinition[];
|
|
178
|
+
node: ClassExpression;
|
|
180
179
|
}
|
|
181
180
|
/**
|
|
182
181
|
* @param node The AST node to check.
|
|
183
182
|
* @deprecated Class components are legacy. This function exists only to support legacy rules.
|
|
184
183
|
*/
|
|
185
|
-
declare function isClassComponent(node: TSESTree.Node): node is
|
|
184
|
+
declare function isClassComponent(node: TSESTree.Node): node is ClassExpression;
|
|
186
185
|
/**
|
|
187
186
|
* @param node The AST node to check.
|
|
188
187
|
* @param context The rule context.
|
|
189
188
|
* @deprecated Class components are legacy. This function exists only to support legacy rules.
|
|
190
189
|
*/
|
|
191
|
-
declare function isClassComponent(node: TSESTree.Node, context: RuleContext): node is
|
|
192
|
-
declare function isClassComponentLoose(node: TSESTree.Node): node is
|
|
190
|
+
declare function isClassComponent(node: TSESTree.Node, context: RuleContext): node is ClassExpression;
|
|
191
|
+
declare function isClassComponentLoose(node: TSESTree.Node): node is ClassExpression;
|
|
193
192
|
/**
|
|
194
193
|
* @param node The AST node to check.
|
|
195
194
|
* @deprecated Class components are legacy. This function exists only to support legacy rules.
|
|
196
195
|
*/
|
|
197
196
|
declare function isPureComponent(node: TSESTree.Node): boolean;
|
|
198
197
|
/** @deprecated Class components are legacy. */
|
|
199
|
-
declare const isRender: (node: TSESTree.Node) => node is
|
|
198
|
+
declare const isRender: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
200
199
|
/** @deprecated Class components are legacy. */
|
|
201
|
-
declare const isComponentDidCatch: (node: TSESTree.Node) => node is
|
|
200
|
+
declare const isComponentDidCatch: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
202
201
|
/** @deprecated Class components are legacy. */
|
|
203
|
-
declare const isComponentDidMount: (node: TSESTree.Node) => node is
|
|
202
|
+
declare const isComponentDidMount: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
204
203
|
/** @deprecated Class components are legacy. */
|
|
205
|
-
declare const isComponentDidUpdate: (node: TSESTree.Node) => node is
|
|
204
|
+
declare const isComponentDidUpdate: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
206
205
|
/** @deprecated Class components are legacy. */
|
|
207
|
-
declare const isComponentWillMount: (node: TSESTree.Node) => node is
|
|
206
|
+
declare const isComponentWillMount: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
208
207
|
/** @deprecated Class components are legacy. */
|
|
209
|
-
declare const isComponentWillReceiveProps: (node: TSESTree.Node) => node is
|
|
208
|
+
declare const isComponentWillReceiveProps: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
210
209
|
/** @deprecated Class components are legacy. */
|
|
211
|
-
declare const isComponentWillUnmount: (node: TSESTree.Node) => node is
|
|
210
|
+
declare const isComponentWillUnmount: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
212
211
|
/** @deprecated Class components are legacy. */
|
|
213
|
-
declare const isComponentWillUpdate: (node: TSESTree.Node) => node is
|
|
212
|
+
declare const isComponentWillUpdate: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
214
213
|
/** @deprecated Class components are legacy. */
|
|
215
|
-
declare const isGetChildContext: (node: TSESTree.Node) => node is
|
|
214
|
+
declare const isGetChildContext: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
216
215
|
/** @deprecated Class components are legacy. */
|
|
217
|
-
declare const isGetInitialState: (node: TSESTree.Node) => node is
|
|
216
|
+
declare const isGetInitialState: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
218
217
|
/** @deprecated Class components are legacy. */
|
|
219
|
-
declare const isGetSnapshotBeforeUpdate: (node: TSESTree.Node) => node is
|
|
218
|
+
declare const isGetSnapshotBeforeUpdate: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
220
219
|
/** @deprecated Class components are legacy. */
|
|
221
|
-
declare const isShouldComponentUpdate: (node: TSESTree.Node) => node is
|
|
220
|
+
declare const isShouldComponentUpdate: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
222
221
|
/** @deprecated Class components are legacy. */
|
|
223
|
-
declare const isUnsafeComponentWillMount: (node: TSESTree.Node) => node is
|
|
222
|
+
declare const isUnsafeComponentWillMount: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
224
223
|
/** @deprecated Class components are legacy. */
|
|
225
|
-
declare const isUnsafeComponentWillReceiveProps: (node: TSESTree.Node) => node is
|
|
224
|
+
declare const isUnsafeComponentWillReceiveProps: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
226
225
|
/** @deprecated Class components are legacy. */
|
|
227
|
-
declare const isUnsafeComponentWillUpdate: (node: TSESTree.Node) => node is
|
|
226
|
+
declare const isUnsafeComponentWillUpdate: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
228
227
|
/** @deprecated Class components are legacy. */
|
|
229
|
-
declare const isGetDefaultProps: (node: TSESTree.Node) => node is
|
|
228
|
+
declare const isGetDefaultProps: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
230
229
|
/** @deprecated Class components are legacy. */
|
|
231
|
-
declare const isGetDerivedStateFromProps: (node: TSESTree.Node) => node is
|
|
230
|
+
declare const isGetDerivedStateFromProps: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
232
231
|
/** @deprecated Class components are legacy. */
|
|
233
|
-
declare const isGetDerivedStateFromError: (node: TSESTree.Node) => node is
|
|
232
|
+
declare const isGetDerivedStateFromError: (node: TSESTree.Node) => node is MethodOrPropertyDefinition;
|
|
234
233
|
/**
|
|
235
234
|
* @param node The AST node to check.
|
|
236
235
|
* @deprecated Class components are legacy. This function exists only to support legacy rules.
|
|
237
236
|
*/
|
|
238
|
-
declare function isRenderMethodLike(node: TSESTree.Node): node is
|
|
239
|
-
declare function isRenderMethodCallback(node:
|
|
237
|
+
declare function isRenderMethodLike(node: TSESTree.Node): node is MethodOrPropertyDefinition;
|
|
238
|
+
declare function isRenderMethodCallback(node: FunctionExpression): boolean;
|
|
240
239
|
/**
|
|
241
240
|
* @param node The call expression node to check.
|
|
242
241
|
* @deprecated Class components are legacy. This function exists only to support legacy rules.
|
|
@@ -275,7 +274,7 @@ type FunctionID = ReturnType<typeof getFunctionId>;
|
|
|
275
274
|
* Represents various AST paths for function declarations.
|
|
276
275
|
* Each tuple type represents a specific function definition pattern.
|
|
277
276
|
*/
|
|
278
|
-
type FunctionInitPath = readonly [TSESTree.FunctionDeclaration] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator,
|
|
277
|
+
type FunctionInitPath = readonly [TSESTree.FunctionDeclaration] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, FunctionExpression] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.CallExpression, FunctionExpression] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.CallExpression, TSESTree.CallExpression, FunctionExpression] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, FunctionExpression] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTree.CallExpression, FunctionExpression] | readonly [TSESTree.VariableDeclaration, TSESTree.VariableDeclarator, TSESTree.ObjectExpression, TSESTree.Property, TSESTree.CallExpression, TSESTree.CallExpression, FunctionExpression] | readonly [TSESTree.ClassDeclaration | TSESTree.ClassExpression, TSESTree.ClassBody, TSESTree.MethodDefinition, FunctionExpression] | readonly [TSESTree.ClassDeclaration | TSESTree.ClassExpression, TSESTree.ClassBody, TSESTree.PropertyDefinition, FunctionExpression];
|
|
279
278
|
/**
|
|
280
279
|
* Represents the kind of a function.
|
|
281
280
|
*/
|
|
@@ -316,14 +315,14 @@ type FunctionSemanticNode = ClientFunctionSemanticNode | ServerFunctionSemanticN
|
|
|
316
315
|
* @param node - The function node to analyze.
|
|
317
316
|
* @returns The identifier node if found, `null` otherwise.
|
|
318
317
|
*/
|
|
319
|
-
declare function getFunctionId(node: TSESTree.Expression |
|
|
318
|
+
declare function getFunctionId(node: TSESTree.Expression | FunctionExpression): TSESTree.ArrayExpression | TSESTree.ArrayPattern | TSESTree.ArrowFunctionExpression | TSESTree.AssignmentExpression | TSESTree.AwaitExpression | TSESTree.PrivateInExpression | TSESTree.SymmetricBinaryExpression | TSESTree.CallExpression | TSESTree.ChainExpression | TSESTree.ClassExpression | TSESTree.ConditionalExpression | TSESTree.FunctionExpression | TSESTree.Identifier | TSESTree.ImportExpression | TSESTree.JSXElement | TSESTree.JSXFragment | TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral | TSESTree.LogicalExpression | TSESTree.MemberExpressionComputedName | TSESTree.MemberExpressionNonComputedName | TSESTree.MetaProperty | TSESTree.NewExpression | TSESTree.ObjectExpression | TSESTree.ObjectPattern | TSESTree.PrivateIdentifier | TSESTree.SequenceExpression | TSESTree.Super | TSESTree.TaggedTemplateExpression | TSESTree.TemplateLiteral | TSESTree.ThisExpression | TSESTree.TSAsExpression | TSESTree.TSInstantiationExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion | TSESTree.UnaryExpressionBitwiseNot | TSESTree.UnaryExpressionDelete | TSESTree.UnaryExpressionMinus | TSESTree.UnaryExpressionNot | TSESTree.UnaryExpressionPlus | TSESTree.UnaryExpressionTypeof | TSESTree.UnaryExpressionVoid | TSESTree.UpdateExpression | TSESTree.YieldExpression | null;
|
|
320
319
|
/**
|
|
321
320
|
* Identifies the initialization path of a function node in the AST.
|
|
322
321
|
*
|
|
323
322
|
* @param node - The function node to analyze.
|
|
324
323
|
* @returns The function initialization path or `null` if not identifiable.
|
|
325
324
|
*/
|
|
326
|
-
declare function getFunctionInitPath(node:
|
|
325
|
+
declare function getFunctionInitPath(node: FunctionExpression): null | FunctionInitPath;
|
|
327
326
|
/**
|
|
328
327
|
* Checks if a specific function call exists in the function initialization path.
|
|
329
328
|
*
|
|
@@ -338,14 +337,14 @@ declare function isFunctionHasCallInInitPath(callName: string, initPath: Functio
|
|
|
338
337
|
* @param node - The function node to check.
|
|
339
338
|
* @returns `true` if the function is empty, `false` otherwise.
|
|
340
339
|
*/
|
|
341
|
-
declare function isFunctionEmpty(node:
|
|
340
|
+
declare function isFunctionEmpty(node: FunctionExpression): boolean;
|
|
342
341
|
/**
|
|
343
342
|
* Gets all directive expression statements from the top of a function body.
|
|
344
343
|
*
|
|
345
344
|
* @param node - The function AST node.
|
|
346
345
|
* @returns An array of directive expression statements.
|
|
347
346
|
*/
|
|
348
|
-
declare function getFunctionDirectives(node:
|
|
347
|
+
declare function getFunctionDirectives(node: FunctionExpression): Directive[];
|
|
349
348
|
/**
|
|
350
349
|
* Checks if a directive with the given name exists in the function directives.
|
|
351
350
|
*
|
|
@@ -353,7 +352,7 @@ declare function getFunctionDirectives(node: TSESTreeFunction): TSESTreeDirectiv
|
|
|
353
352
|
* @param name - The directive name to check (e.g., "use memo", "use no memo").
|
|
354
353
|
* @returns `true` if the directive exists, `false` otherwise.
|
|
355
354
|
*/
|
|
356
|
-
declare function isFunctionHasDirective(node:
|
|
355
|
+
declare function isFunctionHasDirective(node: FunctionExpression, name: string): boolean;
|
|
357
356
|
//#endregion
|
|
358
357
|
//#region src/function-component.d.ts
|
|
359
358
|
/**
|
|
@@ -371,7 +370,7 @@ interface FunctionComponentSemanticNode extends SemanticNode {
|
|
|
371
370
|
/**
|
|
372
371
|
* The AST node of the function
|
|
373
372
|
*/
|
|
374
|
-
node:
|
|
373
|
+
node: FunctionExpression;
|
|
375
374
|
/**
|
|
376
375
|
* Flags describing the component's characteristics
|
|
377
376
|
*/
|
|
@@ -407,7 +406,7 @@ interface FunctionComponentSemanticNode extends SemanticNode {
|
|
|
407
406
|
/**
|
|
408
407
|
* The directives used in the function (ex: "use strict", "use client", etc.)
|
|
409
408
|
*/
|
|
410
|
-
directives:
|
|
409
|
+
directives: Directive[];
|
|
411
410
|
}
|
|
412
411
|
/**
|
|
413
412
|
* Component flag constants
|
|
@@ -446,7 +445,7 @@ declare function isFunctionComponentWrapperCallback(context: RuleContext, node:
|
|
|
446
445
|
* @param node The AST node to get the function component identifier from
|
|
447
446
|
* @internal
|
|
448
447
|
*/
|
|
449
|
-
declare function getFunctionComponentId(context: RuleContext, node:
|
|
448
|
+
declare function getFunctionComponentId(context: RuleContext, node: FunctionExpression): FunctionID;
|
|
450
449
|
/**
|
|
451
450
|
* Check if a string matches the strict component name pattern
|
|
452
451
|
* @param name The name to check
|
|
@@ -464,7 +463,7 @@ declare function isFunctionComponentNameLoose(name: string): boolean;
|
|
|
464
463
|
* @param allowNone Whether to allow no name
|
|
465
464
|
* @returns Whether the function has a loose component name
|
|
466
465
|
*/
|
|
467
|
-
declare function isFunctionWithLooseComponentName(context: RuleContext, fn:
|
|
466
|
+
declare function isFunctionWithLooseComponentName(context: RuleContext, fn: FunctionExpression, allowNone?: boolean): boolean;
|
|
468
467
|
type FunctionComponentDetectionHint = bigint;
|
|
469
468
|
/**
|
|
470
469
|
* Hints for component collector
|
|
@@ -503,7 +502,7 @@ declare const DEFAULT_COMPONENT_DETECTION_HINT: bigint;
|
|
|
503
502
|
* @param hint Component detection hints (bit flags) to customize detection logic
|
|
504
503
|
* @returns `true` if the node is considered a component definition
|
|
505
504
|
*/
|
|
506
|
-
declare function isFunctionComponentDefinition(context: RuleContext, node:
|
|
505
|
+
declare function isFunctionComponentDefinition(context: RuleContext, node: FunctionExpression, hint: bigint): boolean;
|
|
507
506
|
//#endregion
|
|
508
507
|
//#region src/function-component-collector.d.ts
|
|
509
508
|
declare namespace getFunctionComponentCollector {
|
|
@@ -534,7 +533,7 @@ interface HookSemanticNode extends SemanticNode {
|
|
|
534
533
|
/** The identifier of the hook */
|
|
535
534
|
id: FunctionID;
|
|
536
535
|
/** The AST node of the hook */
|
|
537
|
-
node:
|
|
536
|
+
node: FunctionExpression;
|
|
538
537
|
/** The kind of hook */
|
|
539
538
|
kind: "hook";
|
|
540
539
|
/** List of expressions returned by the hook */
|
|
@@ -542,7 +541,7 @@ interface HookSemanticNode extends SemanticNode {
|
|
|
542
541
|
/** The other hooks called by the hook */
|
|
543
542
|
hookCalls: TSESTree.CallExpression[];
|
|
544
543
|
/** The directives used in the function (ex: "use strict", "use client", etc.) */
|
|
545
|
-
directives:
|
|
544
|
+
directives: Directive[];
|
|
546
545
|
}
|
|
547
546
|
declare const REACT_BUILTIN_HOOK_NAMES: readonly ["use", "useActionState", "useCallback", "useContext", "useDebugValue", "useDeferredValue", "useEffect", "useFormStatus", "useId", "useImperativeHandle", "useInsertionEffect", "useLayoutEffect", "useMemo", "useOptimistic", "useReducer", "useRef", "useState", "useSyncExternalStore", "useTransition"];
|
|
548
547
|
/**
|
|
@@ -563,7 +562,7 @@ declare function isHookId(id: TSESTree.Node): id is TSESTree.Identifier | TSESTr
|
|
|
563
562
|
* @param node The function node to check
|
|
564
563
|
* @returns True if the function is a React Hook, false otherwise
|
|
565
564
|
*/
|
|
566
|
-
declare function isHookDefinition(node:
|
|
565
|
+
declare function isHookDefinition(node: FunctionExpression | null): boolean;
|
|
567
566
|
/**
|
|
568
567
|
* Check if the given node is a React Hook call by its name.
|
|
569
568
|
* @param node The node to check.
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { isDirective, isMethodOrProperty, isTypeAssertionExpression, isTypeExpression } from "@eslint-react/ast";
|
|
1
|
+
import { Check, Extract, Select, Traverse, is, isOneOf } from "@eslint-react/ast";
|
|
3
2
|
import { resolveImportSource } from "@eslint-react/var";
|
|
4
3
|
import { AST_NODE_TYPES } from "@typescript-eslint/types";
|
|
5
4
|
import "@eslint-react/eslint";
|
|
@@ -146,7 +145,7 @@ function isAPI(api) {
|
|
|
146
145
|
const func = (context, node) => {
|
|
147
146
|
if (node == null) return false;
|
|
148
147
|
const getText = (n) => context.sourceCode.getText(n);
|
|
149
|
-
const name =
|
|
148
|
+
const name = Extract.fullyQualifiedName(node, getText);
|
|
150
149
|
if (name === api) return true;
|
|
151
150
|
if (name.endsWith(`.${api}`)) return true;
|
|
152
151
|
return false;
|
|
@@ -162,7 +161,7 @@ function isAPICall(api) {
|
|
|
162
161
|
const func = (context, node) => {
|
|
163
162
|
if (node == null) return false;
|
|
164
163
|
if (node.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
165
|
-
return isAPI(api)(context,
|
|
164
|
+
return isAPI(api)(context, Extract.unwrapped(node.callee));
|
|
166
165
|
};
|
|
167
166
|
return dual(2, func);
|
|
168
167
|
}
|
|
@@ -312,7 +311,7 @@ function isPureComponent(node) {
|
|
|
312
311
|
return false;
|
|
313
312
|
}
|
|
314
313
|
function createLifecycleChecker(methodName, isStatic = false) {
|
|
315
|
-
return (node) =>
|
|
314
|
+
return (node) => Check.isMethodOrProperty(node) && node.static === isStatic && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === methodName;
|
|
316
315
|
}
|
|
317
316
|
/** @deprecated Class components are legacy. */
|
|
318
317
|
const isRender = createLifecycleChecker("render");
|
|
@@ -355,7 +354,7 @@ const isGetDerivedStateFromError = createLifecycleChecker("getDerivedStateFromEr
|
|
|
355
354
|
* @deprecated Class components are legacy. This function exists only to support legacy rules.
|
|
356
355
|
*/
|
|
357
356
|
function isRenderMethodLike(node) {
|
|
358
|
-
return
|
|
357
|
+
return Check.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name.startsWith("render") && isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression])(node.parent.parent);
|
|
359
358
|
}
|
|
360
359
|
function isRenderMethodCallback(node) {
|
|
361
360
|
const parent = node.parent;
|
|
@@ -368,7 +367,7 @@ function isRenderMethodCallback(node) {
|
|
|
368
367
|
*/
|
|
369
368
|
function isThisSetStateCall(node) {
|
|
370
369
|
const { callee } = node;
|
|
371
|
-
return callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
370
|
+
return callee.type === AST_NODE_TYPES.MemberExpression && Check.thisExpression(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
372
371
|
}
|
|
373
372
|
/**
|
|
374
373
|
* @param node The assignment expression node to check.
|
|
@@ -376,7 +375,7 @@ function isThisSetStateCall(node) {
|
|
|
376
375
|
*/
|
|
377
376
|
function isAssignmentToThisState(node) {
|
|
378
377
|
const { left } = node;
|
|
379
|
-
return left.type === AST_NODE_TYPES.MemberExpression &&
|
|
378
|
+
return left.type === AST_NODE_TYPES.MemberExpression && Check.thisExpression(left.object) && Extract.propertyName(left.property) === "state";
|
|
380
379
|
}
|
|
381
380
|
|
|
382
381
|
//#endregion
|
|
@@ -395,7 +394,7 @@ function getClassComponentCollector(context) {
|
|
|
395
394
|
if (!isClassComponent(node)) return;
|
|
396
395
|
const id = getClassId(node);
|
|
397
396
|
const key = ulid();
|
|
398
|
-
const name = id == null ? null :
|
|
397
|
+
const name = id == null ? null : Extract.fullyQualifiedName(id, getText);
|
|
399
398
|
components.set(key, {
|
|
400
399
|
id,
|
|
401
400
|
key,
|
|
@@ -439,10 +438,10 @@ function getFunctionId(node) {
|
|
|
439
438
|
case node.parent.type === AST_NODE_TYPES.VariableDeclarator && node.parent.init === node: return node.parent.id;
|
|
440
439
|
case node.parent.type === AST_NODE_TYPES.AssignmentExpression && node.parent.right === node && node.parent.operator === "=": return node.parent.left;
|
|
441
440
|
case node.parent.type === AST_NODE_TYPES.Property && node.parent.value === node && !node.parent.computed: return node.parent.key;
|
|
442
|
-
case isMethodOrProperty(node.parent) && node.parent.value === node: return node.parent.key;
|
|
441
|
+
case Check.isMethodOrProperty(node.parent) && node.parent.value === node: return node.parent.key;
|
|
443
442
|
case node.parent.type === AST_NODE_TYPES.AssignmentPattern && node.parent.right === node: return node.parent.left;
|
|
444
443
|
case node.parent.type === AST_NODE_TYPES.ConditionalExpression: return getFunctionId(node.parent);
|
|
445
|
-
case isTypeAssertionExpression(node.parent): return getFunctionId(node.parent);
|
|
444
|
+
case Check.isTypeAssertionExpression(node.parent): return getFunctionId(node.parent);
|
|
446
445
|
}
|
|
447
446
|
return null;
|
|
448
447
|
}
|
|
@@ -455,7 +454,7 @@ function getFunctionId(node) {
|
|
|
455
454
|
function getFunctionInitPath(node) {
|
|
456
455
|
if (node.type === AST_NODE_TYPES.FunctionDeclaration) return [node];
|
|
457
456
|
let parent = node.parent;
|
|
458
|
-
while (isTypeExpression(parent)) parent = parent.parent;
|
|
457
|
+
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
459
458
|
switch (true) {
|
|
460
459
|
case parent.type === AST_NODE_TYPES.VariableDeclarator: return [
|
|
461
460
|
parent.parent,
|
|
@@ -532,7 +531,7 @@ function getFunctionDirectives(node) {
|
|
|
532
531
|
const directives = [];
|
|
533
532
|
if (node.body.type !== AST_NODE_TYPES.BlockStatement) return directives;
|
|
534
533
|
for (const stmt of node.body.body) {
|
|
535
|
-
if (!
|
|
534
|
+
if (!Check.directive(stmt)) continue;
|
|
536
535
|
directives.push(stmt);
|
|
537
536
|
}
|
|
538
537
|
return directives;
|
|
@@ -589,9 +588,9 @@ function isFunctionComponentWrapperCall(context, node) {
|
|
|
589
588
|
* @returns `true` if the node is a callback function passed to a component wrapper
|
|
590
589
|
*/
|
|
591
590
|
function isFunctionComponentWrapperCallback(context, node) {
|
|
592
|
-
if (!
|
|
591
|
+
if (!Check.isFunction(node)) return false;
|
|
593
592
|
let parent = node.parent;
|
|
594
|
-
while (
|
|
593
|
+
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
595
594
|
if (parent.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
596
595
|
return isFunctionComponentWrapperCall(context, parent);
|
|
597
596
|
}
|
|
@@ -605,7 +604,7 @@ function getFunctionComponentId(context, node) {
|
|
|
605
604
|
const functionId = getFunctionId(node);
|
|
606
605
|
if (functionId != null) return functionId;
|
|
607
606
|
let parent = node.parent;
|
|
608
|
-
while (
|
|
607
|
+
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
609
608
|
if (parent.type === AST_NODE_TYPES.CallExpression && isFunctionComponentWrapperCall(context, parent) && parent.parent.type === AST_NODE_TYPES.VariableDeclarator) return parent.parent.id;
|
|
610
609
|
if (parent.type === AST_NODE_TYPES.CallExpression && isFunctionComponentWrapperCall(context, parent) && parent.parent.type === AST_NODE_TYPES.CallExpression && isFunctionComponentWrapperCall(context, parent.parent) && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator) return parent.parent.parent.id;
|
|
611
610
|
return null;
|
|
@@ -671,15 +670,15 @@ function isFunctionComponentDefinition(context, node, hint) {
|
|
|
671
670
|
case isRenderMethodCallback(node): return false;
|
|
672
671
|
}
|
|
673
672
|
let parent = node.parent;
|
|
674
|
-
while (
|
|
673
|
+
while (Check.isTypeExpression(parent)) parent = parent.parent;
|
|
675
674
|
switch (true) {
|
|
676
|
-
case
|
|
675
|
+
case isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(node) && parent.type === AST_NODE_TYPES.Property && parent.parent.type === AST_NODE_TYPES.ObjectExpression:
|
|
677
676
|
if (hint & FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsObjectMethod) return false;
|
|
678
677
|
break;
|
|
679
|
-
case
|
|
678
|
+
case isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(node) && parent.type === AST_NODE_TYPES.MethodDefinition:
|
|
680
679
|
if (hint & FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsClassMethod) return false;
|
|
681
680
|
break;
|
|
682
|
-
case
|
|
681
|
+
case isOneOf([AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression])(node) && parent.type === AST_NODE_TYPES.Property:
|
|
683
682
|
if (hint & FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsClassProperty) return false;
|
|
684
683
|
break;
|
|
685
684
|
case parent.type === AST_NODE_TYPES.ArrayPattern:
|
|
@@ -698,7 +697,7 @@ function isFunctionComponentDefinition(context, node, hint) {
|
|
|
698
697
|
if (hint & FunctionComponentDetectionHint.DoNotIncludeFunctionDefinedAsArbitraryCallExpressionCallback) return false;
|
|
699
698
|
break;
|
|
700
699
|
}
|
|
701
|
-
const significantParent =
|
|
700
|
+
const significantParent = Traverse.findParent(node, isOneOf([
|
|
702
701
|
AST_NODE_TYPES.JSXExpressionContainer,
|
|
703
702
|
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
704
703
|
AST_NODE_TYPES.FunctionExpression,
|
|
@@ -806,7 +805,7 @@ function isUseStateLikeCall(node, additionalStateHooks = { test: constFalse }) {
|
|
|
806
805
|
if (node.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
807
806
|
switch (true) {
|
|
808
807
|
case node.callee.type === AST_NODE_TYPES.Identifier: return node.callee.name === "useState" || additionalStateHooks.test(node.callee.name);
|
|
809
|
-
case node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier: return
|
|
808
|
+
case node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier: return Extract.propertyName(node.callee.property) === "useState" || additionalStateHooks.test(node.callee.property.name);
|
|
810
809
|
}
|
|
811
810
|
return false;
|
|
812
811
|
}
|
|
@@ -824,9 +823,9 @@ function isUseEffectSetupCallback(node) {
|
|
|
824
823
|
*/
|
|
825
824
|
function isUseEffectCleanupCallback(node) {
|
|
826
825
|
if (node == null) return false;
|
|
827
|
-
const returnStatement =
|
|
828
|
-
const enclosingFunction =
|
|
829
|
-
if (enclosingFunction !==
|
|
826
|
+
const returnStatement = Traverse.findParent(node, is(AST_NODE_TYPES.ReturnStatement));
|
|
827
|
+
const enclosingFunction = Traverse.findParent(node, Check.isFunction);
|
|
828
|
+
if (enclosingFunction !== Traverse.findParent(returnStatement, Check.isFunction)) return false;
|
|
830
829
|
return isUseEffectSetupCallback(enclosingFunction);
|
|
831
830
|
}
|
|
832
831
|
|
|
@@ -846,11 +845,11 @@ function getFunctionComponentCollector(context, options = {}) {
|
|
|
846
845
|
const getCurrentEntry = () => functionEntries.at(-1) ?? null;
|
|
847
846
|
const onFunctionEnter = (node) => {
|
|
848
847
|
const key = ulid();
|
|
849
|
-
const exp =
|
|
848
|
+
const exp = Traverse.findParent(node, (n) => n.type === AST_NODE_TYPES.ExportDefaultDeclaration);
|
|
850
849
|
const isExportDefault = exp != null;
|
|
851
|
-
const isExportDefaultDeclaration = exp != null &&
|
|
850
|
+
const isExportDefaultDeclaration = exp != null && Extract.unwrapped(exp.declaration) === node;
|
|
852
851
|
const id = getFunctionComponentId(context, node);
|
|
853
|
-
const name = id == null ? null :
|
|
852
|
+
const name = id == null ? null : Extract.fullyQualifiedName(id, getText);
|
|
854
853
|
const initPath = getFunctionInitPath(node);
|
|
855
854
|
const directives = getFunctionDirectives(node);
|
|
856
855
|
const entry = {
|
|
@@ -894,7 +893,7 @@ function getFunctionComponentCollector(context, options = {}) {
|
|
|
894
893
|
if (!components.has(entry.key) && !isJsxLike(context, body, hint)) return;
|
|
895
894
|
components.set(entry.key, entry);
|
|
896
895
|
},
|
|
897
|
-
...collectDisplayName ? { [
|
|
896
|
+
...collectDisplayName ? { [Select.displayNameAssignment](node) {
|
|
898
897
|
const { left, right } = node;
|
|
899
898
|
if (left.type !== AST_NODE_TYPES.MemberExpression) return;
|
|
900
899
|
const componentName = left.object.type === AST_NODE_TYPES.Identifier ? left.object.name : null;
|
|
@@ -942,7 +941,7 @@ function getHookCollector(context) {
|
|
|
942
941
|
id,
|
|
943
942
|
key,
|
|
944
943
|
kind: "hook",
|
|
945
|
-
name: id == null ? null :
|
|
944
|
+
name: id == null ? null : Extract.fullyQualifiedName(id, getText),
|
|
946
945
|
directives: [],
|
|
947
946
|
flag: 0n,
|
|
948
947
|
hint: 0n,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.2-next.0",
|
|
4
4
|
"description": "ESLint React's ESLint utility module for static analysis of React core APIs and patterns.",
|
|
5
5
|
"homepage": "https://github.com/Rel1cx/eslint-react",
|
|
6
6
|
"bugs": {
|
|
@@ -35,17 +35,17 @@
|
|
|
35
35
|
"@typescript-eslint/utils": "^8.58.1",
|
|
36
36
|
"ts-pattern": "^5.9.0",
|
|
37
37
|
"ulid": "^3.0.2",
|
|
38
|
-
"@eslint-react/ast": "5.2.
|
|
39
|
-
"@eslint-react/eslint": "5.2.
|
|
40
|
-
"@eslint-react/
|
|
41
|
-
"@eslint-react/
|
|
42
|
-
"@eslint-react/var": "5.2.
|
|
38
|
+
"@eslint-react/ast": "5.2.2-next.0",
|
|
39
|
+
"@eslint-react/eslint": "5.2.2-next.0",
|
|
40
|
+
"@eslint-react/shared": "5.2.2-next.0",
|
|
41
|
+
"@eslint-react/jsx": "5.2.2-next.0",
|
|
42
|
+
"@eslint-react/var": "5.2.2-next.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@typescript-eslint/typescript-estree": "^8.58.1",
|
|
46
46
|
"tsdown": "^0.21.7",
|
|
47
|
-
"@local/
|
|
48
|
-
"@local/
|
|
47
|
+
"@local/eff": "3.0.0-beta.72",
|
|
48
|
+
"@local/configs": "0.0.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"eslint": "^10.2.0",
|