@eslint-react/core 1.28.1-beta.1 → 1.28.1-beta.2
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.mts +19 -42
- package/dist/index.d.ts +19 -42
- package/dist/index.js +61 -72
- package/dist/index.mjs +61 -68
- package/package.json +6 -6
package/dist/index.d.mts
CHANGED
|
@@ -7,16 +7,6 @@ import * as birecord from 'birecord';
|
|
|
7
7
|
import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
|
|
8
8
|
import { Scope } from '@typescript-eslint/scope-manager';
|
|
9
9
|
|
|
10
|
-
interface ERSemanticNode {
|
|
11
|
-
id: _ | TSESTree.Identifier | TSESTree.Identifier[];
|
|
12
|
-
key: string;
|
|
13
|
-
kind: string;
|
|
14
|
-
name: _ | string;
|
|
15
|
-
node: TSESTree.Node;
|
|
16
|
-
flag: bigint;
|
|
17
|
-
hint: bigint;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
10
|
type ERComponentHint = bigint;
|
|
21
11
|
/**
|
|
22
12
|
* hints for component collector
|
|
@@ -61,6 +51,16 @@ declare const ERComponentHint: {
|
|
|
61
51
|
};
|
|
62
52
|
declare const DEFAULT_COMPONENT_HINT: bigint;
|
|
63
53
|
|
|
54
|
+
interface ERSemanticNode {
|
|
55
|
+
id: _ | TSESTree.Identifier | TSESTree.Identifier[];
|
|
56
|
+
key: string;
|
|
57
|
+
kind: string;
|
|
58
|
+
name: _ | string;
|
|
59
|
+
node: TSESTree.Node;
|
|
60
|
+
flag: bigint;
|
|
61
|
+
hint: bigint;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
64
|
type ERComponentFlag = bigint;
|
|
65
65
|
declare const ERComponentFlag: {
|
|
66
66
|
None: bigint;
|
|
@@ -102,6 +102,7 @@ declare namespace useComponentCollector {
|
|
|
102
102
|
type Options = {
|
|
103
103
|
collectDisplayName?: boolean;
|
|
104
104
|
collectHookCalls?: boolean;
|
|
105
|
+
hint?: ERComponentHint;
|
|
105
106
|
};
|
|
106
107
|
type ReturnType = {
|
|
107
108
|
ctx: {
|
|
@@ -115,11 +116,10 @@ declare namespace useComponentCollector {
|
|
|
115
116
|
/**
|
|
116
117
|
* Get a ctx and listeners for the rule to collect function components
|
|
117
118
|
* @param context The ESLint rule context
|
|
118
|
-
* @param hint The hint to use
|
|
119
119
|
* @param options The options to use
|
|
120
120
|
* @returns The component collector
|
|
121
121
|
*/
|
|
122
|
-
declare function useComponentCollector(context: RuleContext,
|
|
122
|
+
declare function useComponentCollector(context: RuleContext, options?: useComponentCollector.Options): useComponentCollector.ReturnType;
|
|
123
123
|
|
|
124
124
|
declare namespace useComponentCollectorLegacy {
|
|
125
125
|
type ReturnType = {
|
|
@@ -251,27 +251,15 @@ declare function isClassComponent(node: TSESTree.Node): node is AST.TSESTreeClas
|
|
|
251
251
|
*/
|
|
252
252
|
declare function isPureComponent(node: TSESTree.Node): boolean;
|
|
253
253
|
|
|
254
|
-
type EREffectKind = "useEffect" | "useLayoutEffect" | "useInsertionEffect";
|
|
255
|
-
|
|
256
|
-
declare function isFunctionOfUseEffectSetup(node: TSESTree.Node | _): boolean | undefined;
|
|
257
|
-
declare function isFunctionOfUseEffectCleanup(node: TSESTree.Node): boolean | undefined;
|
|
258
|
-
|
|
259
254
|
/**
|
|
260
|
-
*
|
|
261
|
-
* @param context The rule context
|
|
262
|
-
* @param node The AST node to check
|
|
263
|
-
* @returns `true` if the node is inside createElement's props
|
|
264
|
-
*/
|
|
265
|
-
declare function isInsideCreateElementProps(context: RuleContext, node: TSESTree.Node): boolean;
|
|
266
|
-
/**
|
|
267
|
-
* Determines whether inside `createElement`'s children.
|
|
268
|
-
* @param context The rule context
|
|
269
|
-
* @param node The AST node to check
|
|
270
|
-
* @returns `true` if the node is inside createElement's children
|
|
255
|
+
* The ESQuery selector for a component display name assignment expression
|
|
271
256
|
*/
|
|
272
|
-
declare
|
|
257
|
+
declare const DISPLAY_NAME_ASSIGNMENT_SELECTOR: string;
|
|
273
258
|
|
|
274
|
-
|
|
259
|
+
type EREffectKind = "useEffect" | "useLayoutEffect" | "useInsertionEffect";
|
|
260
|
+
|
|
261
|
+
declare function isFunctionOfUseEffectSetup(node: TSESTree.Node | _): boolean | undefined;
|
|
262
|
+
declare function isFunctionOfUseEffectCleanup(node: TSESTree.Node | _): boolean | undefined;
|
|
275
263
|
|
|
276
264
|
interface ERHook extends ERSemanticNode {
|
|
277
265
|
id: TSESTree.Identifier | _;
|
|
@@ -327,17 +315,6 @@ interface ERSemanticEntry {
|
|
|
327
315
|
phase: ERPhaseKind;
|
|
328
316
|
}
|
|
329
317
|
|
|
330
|
-
/**
|
|
331
|
-
* The ESQuery selector for a component display name assignment expression
|
|
332
|
-
*/
|
|
333
|
-
declare const DISPLAY_NAME_ASSIGNMENT_SELECTOR: string;
|
|
334
|
-
/**
|
|
335
|
-
* Check if the node is a component display name assignment expression
|
|
336
|
-
* @param node The AST node
|
|
337
|
-
* @returns `true` if the node is a component display name assignment
|
|
338
|
-
*/
|
|
339
|
-
declare function isDisplayNameAssignment(node: TSESTree.Node | _): node is TSESTree.AssignmentExpression;
|
|
340
|
-
|
|
341
318
|
declare function isFromReactLoose(node: TSESTree.Node | _, name: string): boolean;
|
|
342
319
|
declare function isFromReactStrict(node: TSESTree.Node | _, name: string, importSource: string, initialScope: Scope): boolean;
|
|
343
320
|
declare namespace isFromReact {
|
|
@@ -393,4 +370,4 @@ declare const isCreateRefCall: isCallFromReact.ReturnType;
|
|
|
393
370
|
declare const isForwardRefCall: isCallFromReact.ReturnType;
|
|
394
371
|
declare const isMemoCall: isCallFromReact.ReturnType;
|
|
395
372
|
|
|
396
|
-
export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type ERClassComponent, type ERComponent, ERComponentFlag, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectPhaseKind, type ERFunctionComponent, type ERHook, type ERHookKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall,
|
|
373
|
+
export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type ERClassComponent, type ERComponent, ERComponentFlag, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectPhaseKind, type ERFunctionComponent, type ERHook, type ERHookKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactObject, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/dist/index.d.ts
CHANGED
|
@@ -7,16 +7,6 @@ import * as birecord from 'birecord';
|
|
|
7
7
|
import * as _typescript_eslint_utils_ts_eslint from '@typescript-eslint/utils/ts-eslint';
|
|
8
8
|
import { Scope } from '@typescript-eslint/scope-manager';
|
|
9
9
|
|
|
10
|
-
interface ERSemanticNode {
|
|
11
|
-
id: _ | TSESTree.Identifier | TSESTree.Identifier[];
|
|
12
|
-
key: string;
|
|
13
|
-
kind: string;
|
|
14
|
-
name: _ | string;
|
|
15
|
-
node: TSESTree.Node;
|
|
16
|
-
flag: bigint;
|
|
17
|
-
hint: bigint;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
10
|
type ERComponentHint = bigint;
|
|
21
11
|
/**
|
|
22
12
|
* hints for component collector
|
|
@@ -61,6 +51,16 @@ declare const ERComponentHint: {
|
|
|
61
51
|
};
|
|
62
52
|
declare const DEFAULT_COMPONENT_HINT: bigint;
|
|
63
53
|
|
|
54
|
+
interface ERSemanticNode {
|
|
55
|
+
id: _ | TSESTree.Identifier | TSESTree.Identifier[];
|
|
56
|
+
key: string;
|
|
57
|
+
kind: string;
|
|
58
|
+
name: _ | string;
|
|
59
|
+
node: TSESTree.Node;
|
|
60
|
+
flag: bigint;
|
|
61
|
+
hint: bigint;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
64
|
type ERComponentFlag = bigint;
|
|
65
65
|
declare const ERComponentFlag: {
|
|
66
66
|
None: bigint;
|
|
@@ -102,6 +102,7 @@ declare namespace useComponentCollector {
|
|
|
102
102
|
type Options = {
|
|
103
103
|
collectDisplayName?: boolean;
|
|
104
104
|
collectHookCalls?: boolean;
|
|
105
|
+
hint?: ERComponentHint;
|
|
105
106
|
};
|
|
106
107
|
type ReturnType = {
|
|
107
108
|
ctx: {
|
|
@@ -115,11 +116,10 @@ declare namespace useComponentCollector {
|
|
|
115
116
|
/**
|
|
116
117
|
* Get a ctx and listeners for the rule to collect function components
|
|
117
118
|
* @param context The ESLint rule context
|
|
118
|
-
* @param hint The hint to use
|
|
119
119
|
* @param options The options to use
|
|
120
120
|
* @returns The component collector
|
|
121
121
|
*/
|
|
122
|
-
declare function useComponentCollector(context: RuleContext,
|
|
122
|
+
declare function useComponentCollector(context: RuleContext, options?: useComponentCollector.Options): useComponentCollector.ReturnType;
|
|
123
123
|
|
|
124
124
|
declare namespace useComponentCollectorLegacy {
|
|
125
125
|
type ReturnType = {
|
|
@@ -251,27 +251,15 @@ declare function isClassComponent(node: TSESTree.Node): node is AST.TSESTreeClas
|
|
|
251
251
|
*/
|
|
252
252
|
declare function isPureComponent(node: TSESTree.Node): boolean;
|
|
253
253
|
|
|
254
|
-
type EREffectKind = "useEffect" | "useLayoutEffect" | "useInsertionEffect";
|
|
255
|
-
|
|
256
|
-
declare function isFunctionOfUseEffectSetup(node: TSESTree.Node | _): boolean | undefined;
|
|
257
|
-
declare function isFunctionOfUseEffectCleanup(node: TSESTree.Node): boolean | undefined;
|
|
258
|
-
|
|
259
254
|
/**
|
|
260
|
-
*
|
|
261
|
-
* @param context The rule context
|
|
262
|
-
* @param node The AST node to check
|
|
263
|
-
* @returns `true` if the node is inside createElement's props
|
|
264
|
-
*/
|
|
265
|
-
declare function isInsideCreateElementProps(context: RuleContext, node: TSESTree.Node): boolean;
|
|
266
|
-
/**
|
|
267
|
-
* Determines whether inside `createElement`'s children.
|
|
268
|
-
* @param context The rule context
|
|
269
|
-
* @param node The AST node to check
|
|
270
|
-
* @returns `true` if the node is inside createElement's children
|
|
255
|
+
* The ESQuery selector for a component display name assignment expression
|
|
271
256
|
*/
|
|
272
|
-
declare
|
|
257
|
+
declare const DISPLAY_NAME_ASSIGNMENT_SELECTOR: string;
|
|
273
258
|
|
|
274
|
-
|
|
259
|
+
type EREffectKind = "useEffect" | "useLayoutEffect" | "useInsertionEffect";
|
|
260
|
+
|
|
261
|
+
declare function isFunctionOfUseEffectSetup(node: TSESTree.Node | _): boolean | undefined;
|
|
262
|
+
declare function isFunctionOfUseEffectCleanup(node: TSESTree.Node | _): boolean | undefined;
|
|
275
263
|
|
|
276
264
|
interface ERHook extends ERSemanticNode {
|
|
277
265
|
id: TSESTree.Identifier | _;
|
|
@@ -327,17 +315,6 @@ interface ERSemanticEntry {
|
|
|
327
315
|
phase: ERPhaseKind;
|
|
328
316
|
}
|
|
329
317
|
|
|
330
|
-
/**
|
|
331
|
-
* The ESQuery selector for a component display name assignment expression
|
|
332
|
-
*/
|
|
333
|
-
declare const DISPLAY_NAME_ASSIGNMENT_SELECTOR: string;
|
|
334
|
-
/**
|
|
335
|
-
* Check if the node is a component display name assignment expression
|
|
336
|
-
* @param node The AST node
|
|
337
|
-
* @returns `true` if the node is a component display name assignment
|
|
338
|
-
*/
|
|
339
|
-
declare function isDisplayNameAssignment(node: TSESTree.Node | _): node is TSESTree.AssignmentExpression;
|
|
340
|
-
|
|
341
318
|
declare function isFromReactLoose(node: TSESTree.Node | _, name: string): boolean;
|
|
342
319
|
declare function isFromReactStrict(node: TSESTree.Node | _, name: string, importSource: string, initialScope: Scope): boolean;
|
|
343
320
|
declare namespace isFromReact {
|
|
@@ -393,4 +370,4 @@ declare const isCreateRefCall: isCallFromReact.ReturnType;
|
|
|
393
370
|
declare const isForwardRefCall: isCallFromReact.ReturnType;
|
|
394
371
|
declare const isMemoCall: isCallFromReact.ReturnType;
|
|
395
372
|
|
|
396
|
-
export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type ERClassComponent, type ERComponent, ERComponentFlag, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectPhaseKind, type ERFunctionComponent, type ERHook, type ERHookKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall,
|
|
373
|
+
export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type ERClassComponent, type ERComponent, ERComponentFlag, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectPhaseKind, type ERFunctionComponent, type ERHook, type ERHookKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactObject, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var AST5 = require('@eslint-react/ast');
|
|
4
4
|
var eff = require('@eslint-react/eff');
|
|
5
5
|
var JSX3 = require('@eslint-react/jsx');
|
|
6
6
|
var shared = require('@eslint-react/shared');
|
|
@@ -29,13 +29,28 @@ function _interopNamespace(e) {
|
|
|
29
29
|
return Object.freeze(n);
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
var
|
|
32
|
+
var AST5__namespace = /*#__PURE__*/_interopNamespace(AST5);
|
|
33
33
|
var JSX3__namespace = /*#__PURE__*/_interopNamespace(JSX3);
|
|
34
34
|
var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
|
|
35
35
|
var birecord__default = /*#__PURE__*/_interopDefault(birecord);
|
|
36
36
|
|
|
37
37
|
// src/component/component-collector.ts
|
|
38
38
|
|
|
39
|
+
// src/constants.ts
|
|
40
|
+
var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
|
|
41
|
+
"AssignmentExpression",
|
|
42
|
+
"[type]",
|
|
43
|
+
"[operator='=']",
|
|
44
|
+
"[left.type='MemberExpression']",
|
|
45
|
+
"[left.property.name='displayName']"
|
|
46
|
+
].join("");
|
|
47
|
+
|
|
48
|
+
// src/hook/hook-name.ts
|
|
49
|
+
var RE_HOOK_NAME = /^use[A-Z\d]/u;
|
|
50
|
+
function isReactHookName(name) {
|
|
51
|
+
return name === "use" || RE_HOOK_NAME.test(name);
|
|
52
|
+
}
|
|
53
|
+
|
|
39
54
|
// ../../node_modules/.pnpm/valibot@1.0.0-rc.2_typescript@5.8.1-rc/node_modules/valibot/dist/index.js
|
|
40
55
|
var store;
|
|
41
56
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -508,17 +523,6 @@ var ESLintReactSettingsSchema = object({
|
|
|
508
523
|
var DEFAULT_ESLINT_REACT_SETTINGS = {
|
|
509
524
|
...parse(ESLintReactSettingsSchema, {}),
|
|
510
525
|
importSource: "react"};
|
|
511
|
-
var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
|
|
512
|
-
"AssignmentExpression",
|
|
513
|
-
"[type]",
|
|
514
|
-
"[operator='=']",
|
|
515
|
-
"[left.type='MemberExpression']",
|
|
516
|
-
"[left.property.name='displayName']"
|
|
517
|
-
].join("");
|
|
518
|
-
function isDisplayNameAssignment(node) {
|
|
519
|
-
if (node == null) return false;
|
|
520
|
-
return node.type === types.AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === types.AST_NODE_TYPES.MemberExpression && node.left.property.type === types.AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
|
|
521
|
-
}
|
|
522
526
|
function getRequireExpressionArguments(node) {
|
|
523
527
|
return tsPattern.match(node).with({ type: types.AST_NODE_TYPES.CallExpression, arguments: tsPattern.P.select(), callee: { type: types.AST_NODE_TYPES.Identifier, name: "require" } }, eff.identity).with({ type: types.AST_NODE_TYPES.MemberExpression, object: tsPattern.P.select() }, getRequireExpressionArguments).otherwise(() => eff._);
|
|
524
528
|
}
|
|
@@ -537,7 +541,7 @@ function isInitializedFromReact(name, importSource, initialScope) {
|
|
|
537
541
|
}
|
|
538
542
|
const args = getRequireExpressionArguments(init);
|
|
539
543
|
const arg0 = args?.[0];
|
|
540
|
-
if (arg0 == null || !
|
|
544
|
+
if (arg0 == null || !AST5__namespace.isKindOfLiteral(arg0, "string")) {
|
|
541
545
|
return false;
|
|
542
546
|
}
|
|
543
547
|
return arg0.value === importSource || arg0.value.startsWith(`${importSource}/`);
|
|
@@ -632,16 +636,10 @@ var isCreateRefCall = isReactAPICall("createRef");
|
|
|
632
636
|
var isForwardRefCall = isReactAPICall("forwardRef");
|
|
633
637
|
var isMemoCall = isReactAPICall("memo");
|
|
634
638
|
|
|
635
|
-
// src/hook/hook-name.ts
|
|
636
|
-
var RE_HOOK_NAME = /^use[A-Z\d]/u;
|
|
637
|
-
function isReactHookName(name) {
|
|
638
|
-
return name === "use" || RE_HOOK_NAME.test(name);
|
|
639
|
-
}
|
|
640
|
-
|
|
641
639
|
// src/hook/is.ts
|
|
642
640
|
function isReactHook(node) {
|
|
643
641
|
if (node == null) return eff._;
|
|
644
|
-
const id =
|
|
642
|
+
const id = AST5__namespace.getFunctionIdentifier(node);
|
|
645
643
|
return id?.name != null && isReactHookName(id.name);
|
|
646
644
|
}
|
|
647
645
|
function isReactHookCall(node) {
|
|
@@ -735,15 +733,12 @@ var isUseStateCall = eff.flip(isReactHookCallWithName)("useState");
|
|
|
735
733
|
var isUseSyncExternalStoreCall = eff.flip(isReactHookCallWithName)("useSyncExternalStore");
|
|
736
734
|
var isUseTransitionCall = eff.flip(isReactHookCallWithName)("useTransition");
|
|
737
735
|
|
|
738
|
-
// src/hook/
|
|
739
|
-
function isInsideReactHook(node) {
|
|
740
|
-
return isReactHook(AST7__namespace.findParentNode(node, AST7__namespace.isFunction));
|
|
741
|
-
}
|
|
736
|
+
// src/hook/hook-collector.ts
|
|
742
737
|
function useHookCollector() {
|
|
743
738
|
const hooks = /* @__PURE__ */ new Map();
|
|
744
739
|
const functionEntries = [];
|
|
745
740
|
const onFunctionEnter = (node) => {
|
|
746
|
-
const id =
|
|
741
|
+
const id = AST5__namespace.getFunctionIdentifier(node);
|
|
747
742
|
const key = shared.getId();
|
|
748
743
|
const name = id?.name;
|
|
749
744
|
if (name != null && isReactHookName(name)) {
|
|
@@ -839,7 +834,7 @@ function isComponentWrapperCall(context, node) {
|
|
|
839
834
|
return isMemoCall(context, node) || isForwardRefCall(context, node) || isReactHookCallWithNameLoose(node)("useCallback");
|
|
840
835
|
}
|
|
841
836
|
function getFunctionComponentIdentifier(context, node) {
|
|
842
|
-
const functionId =
|
|
837
|
+
const functionId = AST5__namespace.getFunctionIdentifier(node);
|
|
843
838
|
if (functionId != null) {
|
|
844
839
|
return functionId;
|
|
845
840
|
}
|
|
@@ -866,19 +861,6 @@ function hasNoneOrValidComponentName(context, node) {
|
|
|
866
861
|
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
867
862
|
return name != null && isComponentName(name);
|
|
868
863
|
}
|
|
869
|
-
function isInsideCreateElementProps(context, node) {
|
|
870
|
-
const call = AST7__namespace.findParentNode(node, isCreateElementCall(context));
|
|
871
|
-
if (call == null) return false;
|
|
872
|
-
const prop = AST7__namespace.findParentNode(node, AST7__namespace.is(types.AST_NODE_TYPES.ObjectExpression));
|
|
873
|
-
if (prop == null) return false;
|
|
874
|
-
return prop === call.arguments[1];
|
|
875
|
-
}
|
|
876
|
-
function isChildrenOfCreateElement(context, node) {
|
|
877
|
-
const parent = node.parent;
|
|
878
|
-
if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
879
|
-
if (!isCreateElementCall(context, parent)) return false;
|
|
880
|
-
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
881
|
-
}
|
|
882
864
|
function isClassComponent(node) {
|
|
883
865
|
if ("superClass" in node && node.superClass != null) {
|
|
884
866
|
const re = /^(?:Pure)?Component$/u;
|
|
@@ -906,28 +888,28 @@ function isPureComponent(node) {
|
|
|
906
888
|
|
|
907
889
|
// src/component/component-lifecycle.ts
|
|
908
890
|
function isComponentDidMount(node) {
|
|
909
|
-
return
|
|
891
|
+
return AST5__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
910
892
|
}
|
|
911
893
|
function isComponentWillUnmount(node) {
|
|
912
|
-
return
|
|
894
|
+
return AST5__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
|
|
913
895
|
}
|
|
914
896
|
function isComponentDidCatch(node) {
|
|
915
|
-
return
|
|
897
|
+
return AST5__namespace.isMethodOrProperty(node) && !node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
|
|
916
898
|
}
|
|
917
899
|
function isGetDerivedStateFromError(node) {
|
|
918
|
-
return
|
|
900
|
+
return AST5__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
|
|
919
901
|
}
|
|
920
902
|
function isGetDerivedStateFromProps(node) {
|
|
921
|
-
return
|
|
903
|
+
return AST5__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
|
|
922
904
|
}
|
|
923
905
|
function isFunctionOfComponentDidMount(node) {
|
|
924
|
-
return
|
|
906
|
+
return AST5__namespace.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
925
907
|
}
|
|
926
908
|
function isFunctionOfComponentWillUnmount(node) {
|
|
927
|
-
return
|
|
909
|
+
return AST5__namespace.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
928
910
|
}
|
|
929
911
|
function isRenderMethodLike(node) {
|
|
930
|
-
return
|
|
912
|
+
return AST5__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration;
|
|
931
913
|
}
|
|
932
914
|
function isFunctionOfRenderMethod(node) {
|
|
933
915
|
if (!isRenderMethodLike(node.parent)) {
|
|
@@ -936,7 +918,7 @@ function isFunctionOfRenderMethod(node) {
|
|
|
936
918
|
return isClassComponent(node.parent.parent.parent);
|
|
937
919
|
}
|
|
938
920
|
function isInsideRenderMethod(node) {
|
|
939
|
-
return
|
|
921
|
+
return AST5__namespace.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
|
|
940
922
|
}
|
|
941
923
|
|
|
942
924
|
// src/component/hierarchy.ts
|
|
@@ -944,7 +926,7 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
944
926
|
if (isChildrenOfCreateElement(context, node) || isFunctionOfRenderMethod(node)) {
|
|
945
927
|
return false;
|
|
946
928
|
}
|
|
947
|
-
if (hint & ERComponentHint.SkipMapCallback &&
|
|
929
|
+
if (hint & ERComponentHint.SkipMapCallback && AST5__namespace.isMapCallLoose(node.parent)) {
|
|
948
930
|
return false;
|
|
949
931
|
}
|
|
950
932
|
if (hint & ERComponentHint.SkipObjectMethod && isFunctionOfObjectMethod(node.parent)) {
|
|
@@ -956,9 +938,9 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
956
938
|
if (hint & ERComponentHint.SkipClassProperty && isFunctionOfClassProperty(node.parent)) {
|
|
957
939
|
return false;
|
|
958
940
|
}
|
|
959
|
-
const boundaryNode =
|
|
941
|
+
const boundaryNode = AST5__namespace.findParentNode(
|
|
960
942
|
node,
|
|
961
|
-
|
|
943
|
+
AST5__namespace.isOneOf([
|
|
962
944
|
types.AST_NODE_TYPES.JSXExpressionContainer,
|
|
963
945
|
types.AST_NODE_TYPES.ArrowFunctionExpression,
|
|
964
946
|
types.AST_NODE_TYPES.FunctionExpression,
|
|
@@ -968,6 +950,12 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
968
950
|
);
|
|
969
951
|
return boundaryNode == null || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
|
|
970
952
|
}
|
|
953
|
+
function isChildrenOfCreateElement(context, node) {
|
|
954
|
+
const parent = node.parent;
|
|
955
|
+
if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
956
|
+
if (!isCreateElementCall(context, parent)) return false;
|
|
957
|
+
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
958
|
+
}
|
|
971
959
|
function isFunctionOfClassMethod(node) {
|
|
972
960
|
return (node.type === types.AST_NODE_TYPES.FunctionExpression || node.type === types.AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === types.AST_NODE_TYPES.MethodDefinition;
|
|
973
961
|
}
|
|
@@ -979,8 +967,12 @@ function isFunctionOfObjectMethod(node) {
|
|
|
979
967
|
}
|
|
980
968
|
|
|
981
969
|
// src/component/component-collector.ts
|
|
982
|
-
function useComponentCollector(context,
|
|
983
|
-
const {
|
|
970
|
+
function useComponentCollector(context, options = {}) {
|
|
971
|
+
const {
|
|
972
|
+
collectDisplayName = false,
|
|
973
|
+
collectHookCalls = false,
|
|
974
|
+
hint = DEFAULT_COMPONENT_HINT
|
|
975
|
+
} = options;
|
|
984
976
|
const jsxCtx = { getScope: (node) => context.sourceCode.getScope(node) };
|
|
985
977
|
const components = /* @__PURE__ */ new Map();
|
|
986
978
|
const functionEntries = [];
|
|
@@ -993,7 +985,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
993
985
|
const entry = functionEntries.at(-1);
|
|
994
986
|
if (entry == null) return;
|
|
995
987
|
if (!entry.isComponent) return functionEntries.pop();
|
|
996
|
-
const shouldDrop =
|
|
988
|
+
const shouldDrop = AST5__namespace.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
997
989
|
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3__namespace.isJSXValue(r.argument, jsxCtx, hint);
|
|
998
990
|
});
|
|
999
991
|
if (shouldDrop) {
|
|
@@ -1020,7 +1012,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
1020
1012
|
const { body } = entry.node;
|
|
1021
1013
|
const isComponent = hasNoneOrValidComponentName(context, entry.node) && JSX3__namespace.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(context, entry.node, hint);
|
|
1022
1014
|
if (!isComponent) return;
|
|
1023
|
-
const initPath =
|
|
1015
|
+
const initPath = AST5__namespace.getFunctionInitPath(entry.node);
|
|
1024
1016
|
const id = getFunctionComponentIdentifier(context, entry.node);
|
|
1025
1017
|
const name = getComponentNameFromIdentifier(id);
|
|
1026
1018
|
const key = shared.getId();
|
|
@@ -1061,7 +1053,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
1061
1053
|
const isComponent = hasNoneOrValidComponentName(context, entry.node) && JSX3__namespace.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(context, entry.node, hint);
|
|
1062
1054
|
if (!isComponent) return;
|
|
1063
1055
|
entry.isComponent = true;
|
|
1064
|
-
const initPath =
|
|
1056
|
+
const initPath = AST5__namespace.getFunctionInitPath(entry.node);
|
|
1065
1057
|
const id = getFunctionComponentIdentifier(context, entry.node);
|
|
1066
1058
|
const name = getComponentNameFromIdentifier(id);
|
|
1067
1059
|
components.set(entry.key, {
|
|
@@ -1082,10 +1074,10 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
1082
1074
|
}
|
|
1083
1075
|
function getComponentFlag(initPath) {
|
|
1084
1076
|
let flag = ERComponentFlag.None;
|
|
1085
|
-
if (initPath != null &&
|
|
1077
|
+
if (initPath != null && AST5__namespace.hasCallInFunctionInitPath("memo", initPath)) {
|
|
1086
1078
|
flag |= ERComponentFlag.Memo;
|
|
1087
1079
|
}
|
|
1088
|
-
if (initPath != null &&
|
|
1080
|
+
if (initPath != null && AST5__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
1089
1081
|
flag |= ERComponentFlag.ForwardRef;
|
|
1090
1082
|
}
|
|
1091
1083
|
return flag;
|
|
@@ -1102,7 +1094,7 @@ function useComponentCollectorLegacy() {
|
|
|
1102
1094
|
if (!isClassComponent(node)) {
|
|
1103
1095
|
return;
|
|
1104
1096
|
}
|
|
1105
|
-
const id =
|
|
1097
|
+
const id = AST5__namespace.getClassIdentifier(node);
|
|
1106
1098
|
const key = shared.getId();
|
|
1107
1099
|
const flag = isPureComponent(node) ? ERComponentFlag.PureComponent : ERComponentFlag.None;
|
|
1108
1100
|
components.set(
|
|
@@ -1135,7 +1127,7 @@ var ERPhaseRelevance = birecord__default.default({
|
|
|
1135
1127
|
var isInversePhase = eff.dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
|
|
1136
1128
|
function isRenderFunctionLoose(context, node) {
|
|
1137
1129
|
const { body, parent } = node;
|
|
1138
|
-
if (
|
|
1130
|
+
if (AST5__namespace.getFunctionIdentifier(node)?.name.startsWith("render")) {
|
|
1139
1131
|
return parent.type === types.AST_NODE_TYPES.JSXExpressionContainer && parent.parent.type === types.AST_NODE_TYPES.JSXAttribute && parent.parent.name.type === types.AST_NODE_TYPES.JSXIdentifier && parent.parent.name.name.startsWith("render");
|
|
1140
1132
|
}
|
|
1141
1133
|
return JSX3__namespace.isJSXValue(
|
|
@@ -1150,7 +1142,7 @@ function isRenderPropLoose(context, node) {
|
|
|
1150
1142
|
if (node.name.type !== types.AST_NODE_TYPES.JSXIdentifier) {
|
|
1151
1143
|
return false;
|
|
1152
1144
|
}
|
|
1153
|
-
return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer &&
|
|
1145
|
+
return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer && AST5__namespace.isFunction(node.value.expression) && isRenderFunctionLoose(context, node.value.expression);
|
|
1154
1146
|
}
|
|
1155
1147
|
function isDirectValueOfRenderPropertyLoose(node) {
|
|
1156
1148
|
const matching = (node2) => {
|
|
@@ -1162,7 +1154,7 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1162
1154
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
1163
1155
|
return true;
|
|
1164
1156
|
}
|
|
1165
|
-
const parent =
|
|
1157
|
+
const parent = AST5__namespace.findParentNode(node, AST5__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
1166
1158
|
if (parent?.type !== types.AST_NODE_TYPES.JSXAttribute) {
|
|
1167
1159
|
return false;
|
|
1168
1160
|
}
|
|
@@ -1170,17 +1162,18 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1170
1162
|
}
|
|
1171
1163
|
function isThisSetState(node) {
|
|
1172
1164
|
const { callee } = node;
|
|
1173
|
-
return callee.type === types.AST_NODE_TYPES.MemberExpression &&
|
|
1165
|
+
return callee.type === types.AST_NODE_TYPES.MemberExpression && AST5__namespace.isThisExpression(callee.object) && callee.property.type === types.AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
1174
1166
|
}
|
|
1175
1167
|
function isFunctionOfUseEffectSetup(node) {
|
|
1176
1168
|
if (node == null) return eff._;
|
|
1177
1169
|
return node.parent?.type === types.AST_NODE_TYPES.CallExpression && node.parent.callee !== node && node.parent.callee.type === types.AST_NODE_TYPES.Identifier && node.parent.arguments.at(0) === node && isUseEffectCallLoose(node.parent);
|
|
1178
1170
|
}
|
|
1179
1171
|
function isFunctionOfUseEffectCleanup(node) {
|
|
1180
|
-
|
|
1181
|
-
const
|
|
1182
|
-
const
|
|
1183
|
-
|
|
1172
|
+
if (node == null) return eff._;
|
|
1173
|
+
const returnStatement = AST5__namespace.findParentNode(node, AST5__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
|
|
1174
|
+
const enclosingFunction = AST5__namespace.findParentNode(node, AST5__namespace.isFunction);
|
|
1175
|
+
const functionOfReturnStatement = AST5__namespace.findParentNode(returnStatement, AST5__namespace.isFunction);
|
|
1176
|
+
return enclosingFunction === functionOfReturnStatement && isFunctionOfUseEffectSetup(enclosingFunction);
|
|
1184
1177
|
}
|
|
1185
1178
|
|
|
1186
1179
|
exports.DEFAULT_COMPONENT_HINT = DEFAULT_COMPONENT_HINT;
|
|
@@ -1202,7 +1195,6 @@ exports.isChildrenForEach = isChildrenForEach;
|
|
|
1202
1195
|
exports.isChildrenForEachCall = isChildrenForEachCall;
|
|
1203
1196
|
exports.isChildrenMap = isChildrenMap;
|
|
1204
1197
|
exports.isChildrenMapCall = isChildrenMapCall;
|
|
1205
|
-
exports.isChildrenOfCreateElement = isChildrenOfCreateElement;
|
|
1206
1198
|
exports.isChildrenOnly = isChildrenOnly;
|
|
1207
1199
|
exports.isChildrenOnlyCall = isChildrenOnlyCall;
|
|
1208
1200
|
exports.isChildrenToArray = isChildrenToArray;
|
|
@@ -1222,7 +1214,6 @@ exports.isCreateRef = isCreateRef;
|
|
|
1222
1214
|
exports.isCreateRefCall = isCreateRefCall;
|
|
1223
1215
|
exports.isDeclaredInRenderPropLoose = isDeclaredInRenderPropLoose;
|
|
1224
1216
|
exports.isDirectValueOfRenderPropertyLoose = isDirectValueOfRenderPropertyLoose;
|
|
1225
|
-
exports.isDisplayNameAssignment = isDisplayNameAssignment;
|
|
1226
1217
|
exports.isForwardRef = isForwardRef;
|
|
1227
1218
|
exports.isForwardRefCall = isForwardRefCall;
|
|
1228
1219
|
exports.isFromReact = isFromReact;
|
|
@@ -1237,8 +1228,6 @@ exports.isFunctionOfUseEffectSetup = isFunctionOfUseEffectSetup;
|
|
|
1237
1228
|
exports.isGetDerivedStateFromError = isGetDerivedStateFromError;
|
|
1238
1229
|
exports.isGetDerivedStateFromProps = isGetDerivedStateFromProps;
|
|
1239
1230
|
exports.isInitializedFromReact = isInitializedFromReact;
|
|
1240
|
-
exports.isInsideCreateElementProps = isInsideCreateElementProps;
|
|
1241
|
-
exports.isInsideReactHook = isInsideReactHook;
|
|
1242
1231
|
exports.isInsideRenderMethod = isInsideRenderMethod;
|
|
1243
1232
|
exports.isInversePhase = isInversePhase;
|
|
1244
1233
|
exports.isMemo = isMemo;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as AST5 from '@eslint-react/ast';
|
|
2
2
|
import { flip, dual, constFalse, identity, _ } from '@eslint-react/eff';
|
|
3
3
|
import * as JSX3 from '@eslint-react/jsx';
|
|
4
4
|
import { DEFAULT_ESLINT_REACT_SETTINGS as DEFAULT_ESLINT_REACT_SETTINGS$1, unsafeDecodeSettings, getId } from '@eslint-react/shared';
|
|
@@ -9,6 +9,21 @@ import birecord from 'birecord';
|
|
|
9
9
|
|
|
10
10
|
// src/component/component-collector.ts
|
|
11
11
|
|
|
12
|
+
// src/constants.ts
|
|
13
|
+
var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
|
|
14
|
+
"AssignmentExpression",
|
|
15
|
+
"[type]",
|
|
16
|
+
"[operator='=']",
|
|
17
|
+
"[left.type='MemberExpression']",
|
|
18
|
+
"[left.property.name='displayName']"
|
|
19
|
+
].join("");
|
|
20
|
+
|
|
21
|
+
// src/hook/hook-name.ts
|
|
22
|
+
var RE_HOOK_NAME = /^use[A-Z\d]/u;
|
|
23
|
+
function isReactHookName(name) {
|
|
24
|
+
return name === "use" || RE_HOOK_NAME.test(name);
|
|
25
|
+
}
|
|
26
|
+
|
|
12
27
|
// ../../node_modules/.pnpm/valibot@1.0.0-rc.2_typescript@5.8.1-rc/node_modules/valibot/dist/index.js
|
|
13
28
|
var store;
|
|
14
29
|
// @__NO_SIDE_EFFECTS__
|
|
@@ -481,17 +496,6 @@ var ESLintReactSettingsSchema = object({
|
|
|
481
496
|
var DEFAULT_ESLINT_REACT_SETTINGS = {
|
|
482
497
|
...parse(ESLintReactSettingsSchema, {}),
|
|
483
498
|
importSource: "react"};
|
|
484
|
-
var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
|
|
485
|
-
"AssignmentExpression",
|
|
486
|
-
"[type]",
|
|
487
|
-
"[operator='=']",
|
|
488
|
-
"[left.type='MemberExpression']",
|
|
489
|
-
"[left.property.name='displayName']"
|
|
490
|
-
].join("");
|
|
491
|
-
function isDisplayNameAssignment(node) {
|
|
492
|
-
if (node == null) return false;
|
|
493
|
-
return node.type === AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === AST_NODE_TYPES.MemberExpression && node.left.property.type === AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
|
|
494
|
-
}
|
|
495
499
|
function getRequireExpressionArguments(node) {
|
|
496
500
|
return match(node).with({ type: AST_NODE_TYPES.CallExpression, arguments: P.select(), callee: { type: AST_NODE_TYPES.Identifier, name: "require" } }, identity).with({ type: AST_NODE_TYPES.MemberExpression, object: P.select() }, getRequireExpressionArguments).otherwise(() => _);
|
|
497
501
|
}
|
|
@@ -510,7 +514,7 @@ function isInitializedFromReact(name, importSource, initialScope) {
|
|
|
510
514
|
}
|
|
511
515
|
const args = getRequireExpressionArguments(init);
|
|
512
516
|
const arg0 = args?.[0];
|
|
513
|
-
if (arg0 == null || !
|
|
517
|
+
if (arg0 == null || !AST5.isKindOfLiteral(arg0, "string")) {
|
|
514
518
|
return false;
|
|
515
519
|
}
|
|
516
520
|
return arg0.value === importSource || arg0.value.startsWith(`${importSource}/`);
|
|
@@ -605,16 +609,10 @@ var isCreateRefCall = isReactAPICall("createRef");
|
|
|
605
609
|
var isForwardRefCall = isReactAPICall("forwardRef");
|
|
606
610
|
var isMemoCall = isReactAPICall("memo");
|
|
607
611
|
|
|
608
|
-
// src/hook/hook-name.ts
|
|
609
|
-
var RE_HOOK_NAME = /^use[A-Z\d]/u;
|
|
610
|
-
function isReactHookName(name) {
|
|
611
|
-
return name === "use" || RE_HOOK_NAME.test(name);
|
|
612
|
-
}
|
|
613
|
-
|
|
614
612
|
// src/hook/is.ts
|
|
615
613
|
function isReactHook(node) {
|
|
616
614
|
if (node == null) return _;
|
|
617
|
-
const id =
|
|
615
|
+
const id = AST5.getFunctionIdentifier(node);
|
|
618
616
|
return id?.name != null && isReactHookName(id.name);
|
|
619
617
|
}
|
|
620
618
|
function isReactHookCall(node) {
|
|
@@ -708,15 +706,12 @@ var isUseStateCall = flip(isReactHookCallWithName)("useState");
|
|
|
708
706
|
var isUseSyncExternalStoreCall = flip(isReactHookCallWithName)("useSyncExternalStore");
|
|
709
707
|
var isUseTransitionCall = flip(isReactHookCallWithName)("useTransition");
|
|
710
708
|
|
|
711
|
-
// src/hook/
|
|
712
|
-
function isInsideReactHook(node) {
|
|
713
|
-
return isReactHook(AST7.findParentNode(node, AST7.isFunction));
|
|
714
|
-
}
|
|
709
|
+
// src/hook/hook-collector.ts
|
|
715
710
|
function useHookCollector() {
|
|
716
711
|
const hooks = /* @__PURE__ */ new Map();
|
|
717
712
|
const functionEntries = [];
|
|
718
713
|
const onFunctionEnter = (node) => {
|
|
719
|
-
const id =
|
|
714
|
+
const id = AST5.getFunctionIdentifier(node);
|
|
720
715
|
const key = getId();
|
|
721
716
|
const name = id?.name;
|
|
722
717
|
if (name != null && isReactHookName(name)) {
|
|
@@ -812,7 +807,7 @@ function isComponentWrapperCall(context, node) {
|
|
|
812
807
|
return isMemoCall(context, node) || isForwardRefCall(context, node) || isReactHookCallWithNameLoose(node)("useCallback");
|
|
813
808
|
}
|
|
814
809
|
function getFunctionComponentIdentifier(context, node) {
|
|
815
|
-
const functionId =
|
|
810
|
+
const functionId = AST5.getFunctionIdentifier(node);
|
|
816
811
|
if (functionId != null) {
|
|
817
812
|
return functionId;
|
|
818
813
|
}
|
|
@@ -839,19 +834,6 @@ function hasNoneOrValidComponentName(context, node) {
|
|
|
839
834
|
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
840
835
|
return name != null && isComponentName(name);
|
|
841
836
|
}
|
|
842
|
-
function isInsideCreateElementProps(context, node) {
|
|
843
|
-
const call = AST7.findParentNode(node, isCreateElementCall(context));
|
|
844
|
-
if (call == null) return false;
|
|
845
|
-
const prop = AST7.findParentNode(node, AST7.is(AST_NODE_TYPES.ObjectExpression));
|
|
846
|
-
if (prop == null) return false;
|
|
847
|
-
return prop === call.arguments[1];
|
|
848
|
-
}
|
|
849
|
-
function isChildrenOfCreateElement(context, node) {
|
|
850
|
-
const parent = node.parent;
|
|
851
|
-
if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
852
|
-
if (!isCreateElementCall(context, parent)) return false;
|
|
853
|
-
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
854
|
-
}
|
|
855
837
|
function isClassComponent(node) {
|
|
856
838
|
if ("superClass" in node && node.superClass != null) {
|
|
857
839
|
const re = /^(?:Pure)?Component$/u;
|
|
@@ -879,28 +861,28 @@ function isPureComponent(node) {
|
|
|
879
861
|
|
|
880
862
|
// src/component/component-lifecycle.ts
|
|
881
863
|
function isComponentDidMount(node) {
|
|
882
|
-
return
|
|
864
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
883
865
|
}
|
|
884
866
|
function isComponentWillUnmount(node) {
|
|
885
|
-
return
|
|
867
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
|
|
886
868
|
}
|
|
887
869
|
function isComponentDidCatch(node) {
|
|
888
|
-
return
|
|
870
|
+
return AST5.isMethodOrProperty(node) && !node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
|
|
889
871
|
}
|
|
890
872
|
function isGetDerivedStateFromError(node) {
|
|
891
|
-
return
|
|
873
|
+
return AST5.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
|
|
892
874
|
}
|
|
893
875
|
function isGetDerivedStateFromProps(node) {
|
|
894
|
-
return
|
|
876
|
+
return AST5.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
|
|
895
877
|
}
|
|
896
878
|
function isFunctionOfComponentDidMount(node) {
|
|
897
|
-
return
|
|
879
|
+
return AST5.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
898
880
|
}
|
|
899
881
|
function isFunctionOfComponentWillUnmount(node) {
|
|
900
|
-
return
|
|
882
|
+
return AST5.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
901
883
|
}
|
|
902
884
|
function isRenderMethodLike(node) {
|
|
903
|
-
return
|
|
885
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration;
|
|
904
886
|
}
|
|
905
887
|
function isFunctionOfRenderMethod(node) {
|
|
906
888
|
if (!isRenderMethodLike(node.parent)) {
|
|
@@ -909,7 +891,7 @@ function isFunctionOfRenderMethod(node) {
|
|
|
909
891
|
return isClassComponent(node.parent.parent.parent);
|
|
910
892
|
}
|
|
911
893
|
function isInsideRenderMethod(node) {
|
|
912
|
-
return
|
|
894
|
+
return AST5.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
|
|
913
895
|
}
|
|
914
896
|
|
|
915
897
|
// src/component/hierarchy.ts
|
|
@@ -917,7 +899,7 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
917
899
|
if (isChildrenOfCreateElement(context, node) || isFunctionOfRenderMethod(node)) {
|
|
918
900
|
return false;
|
|
919
901
|
}
|
|
920
|
-
if (hint & ERComponentHint.SkipMapCallback &&
|
|
902
|
+
if (hint & ERComponentHint.SkipMapCallback && AST5.isMapCallLoose(node.parent)) {
|
|
921
903
|
return false;
|
|
922
904
|
}
|
|
923
905
|
if (hint & ERComponentHint.SkipObjectMethod && isFunctionOfObjectMethod(node.parent)) {
|
|
@@ -929,9 +911,9 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
929
911
|
if (hint & ERComponentHint.SkipClassProperty && isFunctionOfClassProperty(node.parent)) {
|
|
930
912
|
return false;
|
|
931
913
|
}
|
|
932
|
-
const boundaryNode =
|
|
914
|
+
const boundaryNode = AST5.findParentNode(
|
|
933
915
|
node,
|
|
934
|
-
|
|
916
|
+
AST5.isOneOf([
|
|
935
917
|
AST_NODE_TYPES.JSXExpressionContainer,
|
|
936
918
|
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
937
919
|
AST_NODE_TYPES.FunctionExpression,
|
|
@@ -941,6 +923,12 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
941
923
|
);
|
|
942
924
|
return boundaryNode == null || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
|
|
943
925
|
}
|
|
926
|
+
function isChildrenOfCreateElement(context, node) {
|
|
927
|
+
const parent = node.parent;
|
|
928
|
+
if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
929
|
+
if (!isCreateElementCall(context, parent)) return false;
|
|
930
|
+
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
931
|
+
}
|
|
944
932
|
function isFunctionOfClassMethod(node) {
|
|
945
933
|
return (node.type === AST_NODE_TYPES.FunctionExpression || node.type === AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === AST_NODE_TYPES.MethodDefinition;
|
|
946
934
|
}
|
|
@@ -952,8 +940,12 @@ function isFunctionOfObjectMethod(node) {
|
|
|
952
940
|
}
|
|
953
941
|
|
|
954
942
|
// src/component/component-collector.ts
|
|
955
|
-
function useComponentCollector(context,
|
|
956
|
-
const {
|
|
943
|
+
function useComponentCollector(context, options = {}) {
|
|
944
|
+
const {
|
|
945
|
+
collectDisplayName = false,
|
|
946
|
+
collectHookCalls = false,
|
|
947
|
+
hint = DEFAULT_COMPONENT_HINT
|
|
948
|
+
} = options;
|
|
957
949
|
const jsxCtx = { getScope: (node) => context.sourceCode.getScope(node) };
|
|
958
950
|
const components = /* @__PURE__ */ new Map();
|
|
959
951
|
const functionEntries = [];
|
|
@@ -966,7 +958,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
966
958
|
const entry = functionEntries.at(-1);
|
|
967
959
|
if (entry == null) return;
|
|
968
960
|
if (!entry.isComponent) return functionEntries.pop();
|
|
969
|
-
const shouldDrop =
|
|
961
|
+
const shouldDrop = AST5.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
970
962
|
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3.isJSXValue(r.argument, jsxCtx, hint);
|
|
971
963
|
});
|
|
972
964
|
if (shouldDrop) {
|
|
@@ -993,7 +985,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
993
985
|
const { body } = entry.node;
|
|
994
986
|
const isComponent = hasNoneOrValidComponentName(context, entry.node) && JSX3.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(context, entry.node, hint);
|
|
995
987
|
if (!isComponent) return;
|
|
996
|
-
const initPath =
|
|
988
|
+
const initPath = AST5.getFunctionInitPath(entry.node);
|
|
997
989
|
const id = getFunctionComponentIdentifier(context, entry.node);
|
|
998
990
|
const name = getComponentNameFromIdentifier(id);
|
|
999
991
|
const key = getId();
|
|
@@ -1034,7 +1026,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
1034
1026
|
const isComponent = hasNoneOrValidComponentName(context, entry.node) && JSX3.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(context, entry.node, hint);
|
|
1035
1027
|
if (!isComponent) return;
|
|
1036
1028
|
entry.isComponent = true;
|
|
1037
|
-
const initPath =
|
|
1029
|
+
const initPath = AST5.getFunctionInitPath(entry.node);
|
|
1038
1030
|
const id = getFunctionComponentIdentifier(context, entry.node);
|
|
1039
1031
|
const name = getComponentNameFromIdentifier(id);
|
|
1040
1032
|
components.set(entry.key, {
|
|
@@ -1055,10 +1047,10 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
|
|
|
1055
1047
|
}
|
|
1056
1048
|
function getComponentFlag(initPath) {
|
|
1057
1049
|
let flag = ERComponentFlag.None;
|
|
1058
|
-
if (initPath != null &&
|
|
1050
|
+
if (initPath != null && AST5.hasCallInFunctionInitPath("memo", initPath)) {
|
|
1059
1051
|
flag |= ERComponentFlag.Memo;
|
|
1060
1052
|
}
|
|
1061
|
-
if (initPath != null &&
|
|
1053
|
+
if (initPath != null && AST5.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
1062
1054
|
flag |= ERComponentFlag.ForwardRef;
|
|
1063
1055
|
}
|
|
1064
1056
|
return flag;
|
|
@@ -1075,7 +1067,7 @@ function useComponentCollectorLegacy() {
|
|
|
1075
1067
|
if (!isClassComponent(node)) {
|
|
1076
1068
|
return;
|
|
1077
1069
|
}
|
|
1078
|
-
const id =
|
|
1070
|
+
const id = AST5.getClassIdentifier(node);
|
|
1079
1071
|
const key = getId();
|
|
1080
1072
|
const flag = isPureComponent(node) ? ERComponentFlag.PureComponent : ERComponentFlag.None;
|
|
1081
1073
|
components.set(
|
|
@@ -1108,7 +1100,7 @@ var ERPhaseRelevance = birecord({
|
|
|
1108
1100
|
var isInversePhase = dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
|
|
1109
1101
|
function isRenderFunctionLoose(context, node) {
|
|
1110
1102
|
const { body, parent } = node;
|
|
1111
|
-
if (
|
|
1103
|
+
if (AST5.getFunctionIdentifier(node)?.name.startsWith("render")) {
|
|
1112
1104
|
return parent.type === AST_NODE_TYPES.JSXExpressionContainer && parent.parent.type === AST_NODE_TYPES.JSXAttribute && parent.parent.name.type === AST_NODE_TYPES.JSXIdentifier && parent.parent.name.name.startsWith("render");
|
|
1113
1105
|
}
|
|
1114
1106
|
return JSX3.isJSXValue(
|
|
@@ -1123,7 +1115,7 @@ function isRenderPropLoose(context, node) {
|
|
|
1123
1115
|
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) {
|
|
1124
1116
|
return false;
|
|
1125
1117
|
}
|
|
1126
|
-
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer &&
|
|
1118
|
+
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && AST5.isFunction(node.value.expression) && isRenderFunctionLoose(context, node.value.expression);
|
|
1127
1119
|
}
|
|
1128
1120
|
function isDirectValueOfRenderPropertyLoose(node) {
|
|
1129
1121
|
const matching = (node2) => {
|
|
@@ -1135,7 +1127,7 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1135
1127
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
1136
1128
|
return true;
|
|
1137
1129
|
}
|
|
1138
|
-
const parent =
|
|
1130
|
+
const parent = AST5.findParentNode(node, AST5.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
1139
1131
|
if (parent?.type !== AST_NODE_TYPES.JSXAttribute) {
|
|
1140
1132
|
return false;
|
|
1141
1133
|
}
|
|
@@ -1143,17 +1135,18 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1143
1135
|
}
|
|
1144
1136
|
function isThisSetState(node) {
|
|
1145
1137
|
const { callee } = node;
|
|
1146
|
-
return callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
1138
|
+
return callee.type === AST_NODE_TYPES.MemberExpression && AST5.isThisExpression(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
1147
1139
|
}
|
|
1148
1140
|
function isFunctionOfUseEffectSetup(node) {
|
|
1149
1141
|
if (node == null) return _;
|
|
1150
1142
|
return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && node.parent.callee.type === AST_NODE_TYPES.Identifier && node.parent.arguments.at(0) === node && isUseEffectCallLoose(node.parent);
|
|
1151
1143
|
}
|
|
1152
1144
|
function isFunctionOfUseEffectCleanup(node) {
|
|
1153
|
-
|
|
1154
|
-
const
|
|
1155
|
-
const
|
|
1156
|
-
|
|
1145
|
+
if (node == null) return _;
|
|
1146
|
+
const returnStatement = AST5.findParentNode(node, AST5.is(AST_NODE_TYPES.ReturnStatement));
|
|
1147
|
+
const enclosingFunction = AST5.findParentNode(node, AST5.isFunction);
|
|
1148
|
+
const functionOfReturnStatement = AST5.findParentNode(returnStatement, AST5.isFunction);
|
|
1149
|
+
return enclosingFunction === functionOfReturnStatement && isFunctionOfUseEffectSetup(enclosingFunction);
|
|
1157
1150
|
}
|
|
1158
1151
|
|
|
1159
|
-
export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, ERComponentFlag, ERComponentHint, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall,
|
|
1152
|
+
export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, ERComponentFlag, ERComponentHint, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactObject, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "1.28.1-beta.
|
|
3
|
+
"version": "1.28.1-beta.2",
|
|
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": {
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"@typescript-eslint/utils": "^8.25.0",
|
|
42
42
|
"birecord": "^0.1.1",
|
|
43
43
|
"ts-pattern": "^5.6.2",
|
|
44
|
-
"@eslint-react/ast": "1.28.1-beta.
|
|
45
|
-
"@eslint-react/
|
|
46
|
-
"@eslint-react/
|
|
47
|
-
"@eslint-react/jsx": "1.28.1-beta.
|
|
48
|
-
"@eslint-react/var": "1.28.1-beta.
|
|
44
|
+
"@eslint-react/ast": "1.28.1-beta.2",
|
|
45
|
+
"@eslint-react/shared": "1.28.1-beta.2",
|
|
46
|
+
"@eslint-react/eff": "1.28.1-beta.2",
|
|
47
|
+
"@eslint-react/jsx": "1.28.1-beta.2",
|
|
48
|
+
"@eslint-react/var": "1.28.1-beta.2"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"tsup": "^8.4.0",
|