@eslint-react/core 1.39.0-beta.1 → 1.39.0-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 +46 -21
- package/dist/index.d.ts +46 -21
- package/dist/index.js +123 -106
- package/dist/index.mjs +120 -106
- package/package.json +7 -7
package/dist/index.d.mts
CHANGED
|
@@ -8,7 +8,7 @@ import { Scope } from '@typescript-eslint/scope-manager';
|
|
|
8
8
|
|
|
9
9
|
type ComponentCollectorHint = bigint;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Hints for component collector
|
|
12
12
|
*/
|
|
13
13
|
declare const ComponentCollectorHint: {
|
|
14
14
|
/**
|
|
@@ -48,6 +48,9 @@ declare const ComponentCollectorHint: {
|
|
|
48
48
|
readonly StrictLogical: bigint;
|
|
49
49
|
readonly StrictConditional: bigint;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Default component collector hint
|
|
53
|
+
*/
|
|
51
54
|
declare const DEFAULT_COMPONENT_HINT: bigint;
|
|
52
55
|
|
|
53
56
|
interface SemanticNode {
|
|
@@ -129,13 +132,15 @@ declare namespace useComponentCollectorLegacy {
|
|
|
129
132
|
};
|
|
130
133
|
}
|
|
131
134
|
/**
|
|
132
|
-
* Get a ctx and listeners for the rule to collect class components
|
|
135
|
+
* Get a ctx and listeners object for the rule to collect class components
|
|
133
136
|
* @returns The context and listeners for the rule
|
|
134
137
|
*/
|
|
135
138
|
declare function useComponentCollectorLegacy(): useComponentCollectorLegacy.ReturnType;
|
|
136
139
|
|
|
137
140
|
declare function getFunctionComponentId(context: RuleContext, node: AST.TSESTreeFunction): TSESTree.Identifier | TSESTree.Identifier[] | _;
|
|
138
141
|
|
|
142
|
+
declare function getComponentFlagFromInitPath(initPath: FunctionComponent["initPath"]): bigint;
|
|
143
|
+
|
|
139
144
|
type ComponentKind = "classComponent" | "functionComponent";
|
|
140
145
|
|
|
141
146
|
declare function isComponentDidMount(node: TSESTree.Node): node is AST.TSESTreeMethodOrProperty;
|
|
@@ -147,22 +152,6 @@ declare function isFunctionOfComponentDidMount(node: TSESTree.Node): boolean;
|
|
|
147
152
|
declare function isFunctionOfComponentWillUnmount(node: TSESTree.Node): boolean;
|
|
148
153
|
declare function isRenderMethodLike(node: TSESTree.Node): node is AST.TSESTreeMethodOrProperty;
|
|
149
154
|
declare function isFunctionOfRenderMethod(node: AST.TSESTreeFunction): boolean;
|
|
150
|
-
/**
|
|
151
|
-
* Check whether given node is declared inside class component's render block
|
|
152
|
-
* ```tsx
|
|
153
|
-
* class Component extends React.Component {
|
|
154
|
-
* render() {
|
|
155
|
-
* class NestedClassComponent extends React.Component {
|
|
156
|
-
* render() { return <div />; }
|
|
157
|
-
* }
|
|
158
|
-
* const nestedFunctionComponent = () => <div />;
|
|
159
|
-
* }
|
|
160
|
-
* }
|
|
161
|
-
* ```
|
|
162
|
-
* @param node The AST node being checked
|
|
163
|
-
* @returns `true` if node is inside class component's render block, `false` if not
|
|
164
|
-
*/
|
|
165
|
-
declare function isInsideRenderMethod(node: TSESTree.Node): boolean;
|
|
166
155
|
|
|
167
156
|
declare const RE_COMPONENT_NAME: RegExp;
|
|
168
157
|
declare const RE_COMPONENT_NAME_LOOSE: RegExp;
|
|
@@ -237,8 +226,44 @@ type ComponentStateKind = "actionState" | "state";
|
|
|
237
226
|
declare function isThisSetState(node: TSESTree.CallExpression): boolean;
|
|
238
227
|
declare function isAssignmentToThisState(node: TSESTree.AssignmentExpression): boolean;
|
|
239
228
|
|
|
240
|
-
/**
|
|
241
|
-
|
|
229
|
+
/**
|
|
230
|
+
* Check if the node is a call expression for a component wrapper
|
|
231
|
+
* @param context The ESLint rule context
|
|
232
|
+
* @param node The node to check
|
|
233
|
+
* @returns `true` if the node is a call expression for a component wrapper
|
|
234
|
+
*/
|
|
235
|
+
declare function isComponentWrapperCall(context: RuleContext, node: TSESTree.Node): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Check if the node is a call expression for a component wrapper loosely
|
|
238
|
+
* @param context The ESLint rule context
|
|
239
|
+
* @param node The node to check
|
|
240
|
+
* @returns `true` if the node is a call expression for a component wrapper loosely
|
|
241
|
+
*/
|
|
242
|
+
declare function isComponentWrapperCallLoose(context: RuleContext, node: TSESTree.Node): boolean;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Determines whether inside `createElement`'s children.
|
|
246
|
+
* @param context The rule context
|
|
247
|
+
* @param node The AST node to check
|
|
248
|
+
* @returns `true` if the node is inside createElement's children
|
|
249
|
+
*/
|
|
250
|
+
declare function isChildrenOfCreateElement(context: RuleContext, node: TSESTree.Node): boolean;
|
|
251
|
+
/**
|
|
252
|
+
* Check whether given node is declared inside class component's render block
|
|
253
|
+
* ```tsx
|
|
254
|
+
* class Component extends React.Component {
|
|
255
|
+
* render() {
|
|
256
|
+
* class NestedClassComponent extends React.Component {
|
|
257
|
+
* render() { return <div />; }
|
|
258
|
+
* }
|
|
259
|
+
* const nestedFunctionComponent = () => <div />;
|
|
260
|
+
* }
|
|
261
|
+
* }
|
|
262
|
+
* ```
|
|
263
|
+
* @param node The AST node being checked
|
|
264
|
+
* @returns `true` if node is inside class component's render block, `false` if not
|
|
265
|
+
*/
|
|
266
|
+
declare function isInsideRenderMethod(node: TSESTree.Node): boolean;
|
|
242
267
|
|
|
243
268
|
/**
|
|
244
269
|
* Check if a node is a React class component
|
|
@@ -391,4 +416,4 @@ declare const isCreateRefCall: isCallFromReact.ReturnType;
|
|
|
391
416
|
declare const isForwardRefCall: isCallFromReact.ReturnType;
|
|
392
417
|
declare const isMemoCall: isCallFromReact.ReturnType;
|
|
393
418
|
|
|
394
|
-
export { type ClassComponent, type Component, ComponentCollectorHint, type ComponentEffectPhaseKind, ComponentFlag, type ComponentKind, type ComponentLifecyclePhaseKind, type ComponentPhaseKind, ComponentPhaseRelevance, type ComponentStateKind, DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type EffectKind, type FunctionComponent, type Hook, type HookKind, RE_COMPONENT_NAME, RE_COMPONENT_NAME_LOOSE, RE_HOOK_NAME, type SemanticEntry, type SemanticNode, getComponentNameFromId, getFunctionComponentId, getInstanceId, hasNoneOrLooseComponentName,
|
|
419
|
+
export { type ClassComponent, type Component, ComponentCollectorHint, type ComponentEffectPhaseKind, ComponentFlag, type ComponentKind, type ComponentLifecyclePhaseKind, type ComponentPhaseKind, ComponentPhaseRelevance, type ComponentStateKind, DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type EffectKind, type FunctionComponent, type Hook, type HookKind, RE_COMPONENT_NAME, RE_COMPONENT_NAME_LOOSE, RE_HOOK_NAME, type SemanticEntry, type SemanticNode, getComponentFlagFromInitPath, getComponentNameFromId, getFunctionComponentId, getInstanceId, hasNoneOrLooseComponentName, isAssignmentToThisState, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentNameLoose, isComponentWillUnmount, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactObject, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideRenderMethod, isInstanceIdEqual, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isReactHookNameLoose, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { Scope } from '@typescript-eslint/scope-manager';
|
|
|
8
8
|
|
|
9
9
|
type ComponentCollectorHint = bigint;
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Hints for component collector
|
|
12
12
|
*/
|
|
13
13
|
declare const ComponentCollectorHint: {
|
|
14
14
|
/**
|
|
@@ -48,6 +48,9 @@ declare const ComponentCollectorHint: {
|
|
|
48
48
|
readonly StrictLogical: bigint;
|
|
49
49
|
readonly StrictConditional: bigint;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Default component collector hint
|
|
53
|
+
*/
|
|
51
54
|
declare const DEFAULT_COMPONENT_HINT: bigint;
|
|
52
55
|
|
|
53
56
|
interface SemanticNode {
|
|
@@ -129,13 +132,15 @@ declare namespace useComponentCollectorLegacy {
|
|
|
129
132
|
};
|
|
130
133
|
}
|
|
131
134
|
/**
|
|
132
|
-
* Get a ctx and listeners for the rule to collect class components
|
|
135
|
+
* Get a ctx and listeners object for the rule to collect class components
|
|
133
136
|
* @returns The context and listeners for the rule
|
|
134
137
|
*/
|
|
135
138
|
declare function useComponentCollectorLegacy(): useComponentCollectorLegacy.ReturnType;
|
|
136
139
|
|
|
137
140
|
declare function getFunctionComponentId(context: RuleContext, node: AST.TSESTreeFunction): TSESTree.Identifier | TSESTree.Identifier[] | _;
|
|
138
141
|
|
|
142
|
+
declare function getComponentFlagFromInitPath(initPath: FunctionComponent["initPath"]): bigint;
|
|
143
|
+
|
|
139
144
|
type ComponentKind = "classComponent" | "functionComponent";
|
|
140
145
|
|
|
141
146
|
declare function isComponentDidMount(node: TSESTree.Node): node is AST.TSESTreeMethodOrProperty;
|
|
@@ -147,22 +152,6 @@ declare function isFunctionOfComponentDidMount(node: TSESTree.Node): boolean;
|
|
|
147
152
|
declare function isFunctionOfComponentWillUnmount(node: TSESTree.Node): boolean;
|
|
148
153
|
declare function isRenderMethodLike(node: TSESTree.Node): node is AST.TSESTreeMethodOrProperty;
|
|
149
154
|
declare function isFunctionOfRenderMethod(node: AST.TSESTreeFunction): boolean;
|
|
150
|
-
/**
|
|
151
|
-
* Check whether given node is declared inside class component's render block
|
|
152
|
-
* ```tsx
|
|
153
|
-
* class Component extends React.Component {
|
|
154
|
-
* render() {
|
|
155
|
-
* class NestedClassComponent extends React.Component {
|
|
156
|
-
* render() { return <div />; }
|
|
157
|
-
* }
|
|
158
|
-
* const nestedFunctionComponent = () => <div />;
|
|
159
|
-
* }
|
|
160
|
-
* }
|
|
161
|
-
* ```
|
|
162
|
-
* @param node The AST node being checked
|
|
163
|
-
* @returns `true` if node is inside class component's render block, `false` if not
|
|
164
|
-
*/
|
|
165
|
-
declare function isInsideRenderMethod(node: TSESTree.Node): boolean;
|
|
166
155
|
|
|
167
156
|
declare const RE_COMPONENT_NAME: RegExp;
|
|
168
157
|
declare const RE_COMPONENT_NAME_LOOSE: RegExp;
|
|
@@ -237,8 +226,44 @@ type ComponentStateKind = "actionState" | "state";
|
|
|
237
226
|
declare function isThisSetState(node: TSESTree.CallExpression): boolean;
|
|
238
227
|
declare function isAssignmentToThisState(node: TSESTree.AssignmentExpression): boolean;
|
|
239
228
|
|
|
240
|
-
/**
|
|
241
|
-
|
|
229
|
+
/**
|
|
230
|
+
* Check if the node is a call expression for a component wrapper
|
|
231
|
+
* @param context The ESLint rule context
|
|
232
|
+
* @param node The node to check
|
|
233
|
+
* @returns `true` if the node is a call expression for a component wrapper
|
|
234
|
+
*/
|
|
235
|
+
declare function isComponentWrapperCall(context: RuleContext, node: TSESTree.Node): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Check if the node is a call expression for a component wrapper loosely
|
|
238
|
+
* @param context The ESLint rule context
|
|
239
|
+
* @param node The node to check
|
|
240
|
+
* @returns `true` if the node is a call expression for a component wrapper loosely
|
|
241
|
+
*/
|
|
242
|
+
declare function isComponentWrapperCallLoose(context: RuleContext, node: TSESTree.Node): boolean;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Determines whether inside `createElement`'s children.
|
|
246
|
+
* @param context The rule context
|
|
247
|
+
* @param node The AST node to check
|
|
248
|
+
* @returns `true` if the node is inside createElement's children
|
|
249
|
+
*/
|
|
250
|
+
declare function isChildrenOfCreateElement(context: RuleContext, node: TSESTree.Node): boolean;
|
|
251
|
+
/**
|
|
252
|
+
* Check whether given node is declared inside class component's render block
|
|
253
|
+
* ```tsx
|
|
254
|
+
* class Component extends React.Component {
|
|
255
|
+
* render() {
|
|
256
|
+
* class NestedClassComponent extends React.Component {
|
|
257
|
+
* render() { return <div />; }
|
|
258
|
+
* }
|
|
259
|
+
* const nestedFunctionComponent = () => <div />;
|
|
260
|
+
* }
|
|
261
|
+
* }
|
|
262
|
+
* ```
|
|
263
|
+
* @param node The AST node being checked
|
|
264
|
+
* @returns `true` if node is inside class component's render block, `false` if not
|
|
265
|
+
*/
|
|
266
|
+
declare function isInsideRenderMethod(node: TSESTree.Node): boolean;
|
|
242
267
|
|
|
243
268
|
/**
|
|
244
269
|
* Check if a node is a React class component
|
|
@@ -391,4 +416,4 @@ declare const isCreateRefCall: isCallFromReact.ReturnType;
|
|
|
391
416
|
declare const isForwardRefCall: isCallFromReact.ReturnType;
|
|
392
417
|
declare const isMemoCall: isCallFromReact.ReturnType;
|
|
393
418
|
|
|
394
|
-
export { type ClassComponent, type Component, ComponentCollectorHint, type ComponentEffectPhaseKind, ComponentFlag, type ComponentKind, type ComponentLifecyclePhaseKind, type ComponentPhaseKind, ComponentPhaseRelevance, type ComponentStateKind, DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type EffectKind, type FunctionComponent, type Hook, type HookKind, RE_COMPONENT_NAME, RE_COMPONENT_NAME_LOOSE, RE_HOOK_NAME, type SemanticEntry, type SemanticNode, getComponentNameFromId, getFunctionComponentId, getInstanceId, hasNoneOrLooseComponentName,
|
|
419
|
+
export { type ClassComponent, type Component, ComponentCollectorHint, type ComponentEffectPhaseKind, ComponentFlag, type ComponentKind, type ComponentLifecyclePhaseKind, type ComponentPhaseKind, ComponentPhaseRelevance, type ComponentStateKind, DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type EffectKind, type FunctionComponent, type Hook, type HookKind, RE_COMPONENT_NAME, RE_COMPONENT_NAME_LOOSE, RE_HOOK_NAME, type SemanticEntry, type SemanticNode, getComponentFlagFromInitPath, getComponentNameFromId, getFunctionComponentId, getInstanceId, hasNoneOrLooseComponentName, isAssignmentToThisState, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentNameLoose, isComponentWillUnmount, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactObject, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideRenderMethod, isInstanceIdEqual, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isReactHookNameLoose, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, 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');
|
|
@@ -30,7 +30,7 @@ function _interopNamespace(e) {
|
|
|
30
30
|
return Object.freeze(n);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
var
|
|
33
|
+
var AST5__namespace = /*#__PURE__*/_interopNamespace(AST5);
|
|
34
34
|
var JSX3__namespace = /*#__PURE__*/_interopNamespace(JSX3);
|
|
35
35
|
var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
|
|
36
36
|
var birecord__default = /*#__PURE__*/_interopDefault(birecord);
|
|
@@ -560,7 +560,7 @@ function isInitializedFromReact(name, importSource, initialScope) {
|
|
|
560
560
|
}
|
|
561
561
|
const args = getRequireExpressionArguments(init);
|
|
562
562
|
const arg0 = args?.[0];
|
|
563
|
-
if (arg0 == null || !
|
|
563
|
+
if (arg0 == null || !AST5__namespace.isKindOfLiteral(arg0, "string")) {
|
|
564
564
|
return false;
|
|
565
565
|
}
|
|
566
566
|
return arg0.value === importSource || arg0.value.startsWith(`${importSource}/`);
|
|
@@ -625,7 +625,7 @@ function isCallFromReactObject(objectName, propertyName) {
|
|
|
625
625
|
});
|
|
626
626
|
}
|
|
627
627
|
function isInstanceIdEqual(context, a, b) {
|
|
628
|
-
return
|
|
628
|
+
return AST5__namespace.isNodeEqual(a, b) || VAR__namespace.isNodeValueEqual(a, b, [
|
|
629
629
|
context.sourceCode.getScope(a),
|
|
630
630
|
context.sourceCode.getScope(b)
|
|
631
631
|
]);
|
|
@@ -664,7 +664,7 @@ var isMemoCall = isReactAPICall("memo");
|
|
|
664
664
|
// src/hook/is.ts
|
|
665
665
|
function isReactHook(node) {
|
|
666
666
|
if (node == null) return false;
|
|
667
|
-
const id =
|
|
667
|
+
const id = AST5__namespace.getFunctionIdentifier(node);
|
|
668
668
|
return id?.name != null && isReactHookName(id.name);
|
|
669
669
|
}
|
|
670
670
|
function isReactHookCall(node) {
|
|
@@ -767,7 +767,7 @@ function useHookCollector() {
|
|
|
767
767
|
const hooks = /* @__PURE__ */ new Map();
|
|
768
768
|
const functionEntries = [];
|
|
769
769
|
const onFunctionEnter = (node) => {
|
|
770
|
-
const id =
|
|
770
|
+
const id = AST5__namespace.getFunctionIdentifier(node);
|
|
771
771
|
const key = shared.getId();
|
|
772
772
|
const name = id?.name;
|
|
773
773
|
if (name != null && isReactHookName(name)) {
|
|
@@ -846,54 +846,6 @@ var ComponentCollectorHint = {
|
|
|
846
846
|
SkipClassProperty: 1n << 69n
|
|
847
847
|
};
|
|
848
848
|
var DEFAULT_COMPONENT_HINT = 0n | ComponentCollectorHint.SkipBooleanLiteral | ComponentCollectorHint.SkipEmptyArray | ComponentCollectorHint.SkipArrayMapArgument | ComponentCollectorHint.SkipNumberLiteral | ComponentCollectorHint.SkipStringLiteral | ComponentCollectorHint.SkipUndefined | ComponentCollectorHint.StrictArray | ComponentCollectorHint.StrictConditional | ComponentCollectorHint.StrictLogical;
|
|
849
|
-
|
|
850
|
-
// src/component/component-flag.ts
|
|
851
|
-
var ComponentFlag = {
|
|
852
|
-
None: 0n,
|
|
853
|
-
PureComponent: 1n << 0n,
|
|
854
|
-
CreateElement: 1n << 1n,
|
|
855
|
-
Memo: 1n << 2n,
|
|
856
|
-
ForwardRef: 1n << 3n,
|
|
857
|
-
Async: 1n << 4n
|
|
858
|
-
};
|
|
859
|
-
function isComponentWrapperCall(context, node) {
|
|
860
|
-
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
861
|
-
return false;
|
|
862
|
-
}
|
|
863
|
-
return isMemoCall(context, node) || isForwardRefCall(context, node) || isReactHookCallWithNameLoose(node)("useCallback");
|
|
864
|
-
}
|
|
865
|
-
function getFunctionComponentId(context, node) {
|
|
866
|
-
const functionId = AST6__namespace.getFunctionIdentifier(node);
|
|
867
|
-
if (functionId != null) {
|
|
868
|
-
return functionId;
|
|
869
|
-
}
|
|
870
|
-
const { parent } = node;
|
|
871
|
-
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent) && parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator && parent.parent.id.type === types.AST_NODE_TYPES.Identifier) {
|
|
872
|
-
return parent.parent.id;
|
|
873
|
-
}
|
|
874
|
-
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent) && parent.parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent.parent) && parent.parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator && parent.parent.parent.id.type === types.AST_NODE_TYPES.Identifier) {
|
|
875
|
-
return parent.parent.parent.id;
|
|
876
|
-
}
|
|
877
|
-
return eff._;
|
|
878
|
-
}
|
|
879
|
-
var RE_COMPONENT_NAME = /^[A-Z]/u;
|
|
880
|
-
var RE_COMPONENT_NAME_LOOSE = /^_?[A-Z]/u;
|
|
881
|
-
function isComponentName(name) {
|
|
882
|
-
return RE_COMPONENT_NAME.test(name);
|
|
883
|
-
}
|
|
884
|
-
function isComponentNameLoose(name) {
|
|
885
|
-
return RE_COMPONENT_NAME_LOOSE.test(name);
|
|
886
|
-
}
|
|
887
|
-
function getComponentNameFromId(id) {
|
|
888
|
-
if (id == null) return eff._;
|
|
889
|
-
return Array.isArray(id) ? id.map((n) => n.name).join(".") : id.name;
|
|
890
|
-
}
|
|
891
|
-
function hasNoneOrLooseComponentName(context, fn) {
|
|
892
|
-
const id = getFunctionComponentId(context, fn);
|
|
893
|
-
if (id == null) return true;
|
|
894
|
-
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
895
|
-
return name != null && isComponentNameLoose(name);
|
|
896
|
-
}
|
|
897
849
|
function isClassComponent(node) {
|
|
898
850
|
if ("superClass" in node && node.superClass != null) {
|
|
899
851
|
const re = /^(?:Pure)?Component$/u;
|
|
@@ -921,28 +873,28 @@ function isPureComponent(node) {
|
|
|
921
873
|
|
|
922
874
|
// src/component/component-lifecycle.ts
|
|
923
875
|
function isComponentDidMount(node) {
|
|
924
|
-
return
|
|
876
|
+
return AST5__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
925
877
|
}
|
|
926
878
|
function isComponentWillUnmount(node) {
|
|
927
|
-
return
|
|
879
|
+
return AST5__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
|
|
928
880
|
}
|
|
929
881
|
function isComponentDidCatch(node) {
|
|
930
|
-
return
|
|
882
|
+
return AST5__namespace.isMethodOrProperty(node) && !node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
|
|
931
883
|
}
|
|
932
884
|
function isGetDerivedStateFromError(node) {
|
|
933
|
-
return
|
|
885
|
+
return AST5__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
|
|
934
886
|
}
|
|
935
887
|
function isGetDerivedStateFromProps(node) {
|
|
936
|
-
return
|
|
888
|
+
return AST5__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
|
|
937
889
|
}
|
|
938
890
|
function isFunctionOfComponentDidMount(node) {
|
|
939
|
-
return
|
|
891
|
+
return AST5__namespace.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
940
892
|
}
|
|
941
893
|
function isFunctionOfComponentWillUnmount(node) {
|
|
942
|
-
return
|
|
894
|
+
return AST5__namespace.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
943
895
|
}
|
|
944
896
|
function isRenderMethodLike(node) {
|
|
945
|
-
return
|
|
897
|
+
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;
|
|
946
898
|
}
|
|
947
899
|
function isFunctionOfRenderMethod(node) {
|
|
948
900
|
if (!isRenderMethodLike(node.parent)) {
|
|
@@ -950,12 +902,35 @@ function isFunctionOfRenderMethod(node) {
|
|
|
950
902
|
}
|
|
951
903
|
return isClassComponent(node.parent.parent.parent);
|
|
952
904
|
}
|
|
905
|
+
function isChildrenOfCreateElement(context, node) {
|
|
906
|
+
const parent = node.parent;
|
|
907
|
+
if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
908
|
+
if (!isCreateElementCall(context, parent)) return false;
|
|
909
|
+
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
910
|
+
}
|
|
953
911
|
function isInsideRenderMethod(node) {
|
|
954
|
-
return
|
|
912
|
+
return AST5__namespace.findParentNode(node, (n) => isRenderMethodLike(n) && isClassComponent(n.parent.parent)) != null;
|
|
955
913
|
}
|
|
956
914
|
|
|
957
|
-
// src/component/
|
|
958
|
-
|
|
915
|
+
// src/component/component-definition.ts
|
|
916
|
+
var isFunctionOfClassMethod = tsPattern.isMatching({
|
|
917
|
+
type: tsPattern.P.union(types.AST_NODE_TYPES.ArrowFunctionExpression, types.AST_NODE_TYPES.FunctionExpression),
|
|
918
|
+
parent: types.AST_NODE_TYPES.MethodDefinition
|
|
919
|
+
});
|
|
920
|
+
var isFunctionOfClassProperty = tsPattern.isMatching({
|
|
921
|
+
type: tsPattern.P.union(types.AST_NODE_TYPES.ArrowFunctionExpression, types.AST_NODE_TYPES.FunctionExpression),
|
|
922
|
+
parent: types.AST_NODE_TYPES.Property
|
|
923
|
+
});
|
|
924
|
+
var isFunctionOfObjectMethod = tsPattern.isMatching({
|
|
925
|
+
type: tsPattern.P.union(types.AST_NODE_TYPES.ArrowFunctionExpression, types.AST_NODE_TYPES.FunctionExpression),
|
|
926
|
+
parent: {
|
|
927
|
+
type: types.AST_NODE_TYPES.Property,
|
|
928
|
+
parent: {
|
|
929
|
+
type: types.AST_NODE_TYPES.ObjectExpression
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
});
|
|
933
|
+
function isValidComponentDefinition(context, node, hint) {
|
|
959
934
|
if (isChildrenOfCreateElement(context, node) || isFunctionOfRenderMethod(node)) {
|
|
960
935
|
return false;
|
|
961
936
|
}
|
|
@@ -968,12 +943,12 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
968
943
|
if (hint & ComponentCollectorHint.SkipClassProperty && isFunctionOfClassProperty(node.parent)) {
|
|
969
944
|
return false;
|
|
970
945
|
}
|
|
971
|
-
if (hint & ComponentCollectorHint.SkipArrayMapArgument &&
|
|
946
|
+
if (hint & ComponentCollectorHint.SkipArrayMapArgument && AST5__namespace.isArrayMapCallLoose(node.parent)) {
|
|
972
947
|
return false;
|
|
973
948
|
}
|
|
974
|
-
const boundaryNode =
|
|
949
|
+
const boundaryNode = AST5__namespace.findParentNode(
|
|
975
950
|
node,
|
|
976
|
-
|
|
951
|
+
AST5__namespace.isOneOf([
|
|
977
952
|
types.AST_NODE_TYPES.JSXExpressionContainer,
|
|
978
953
|
types.AST_NODE_TYPES.ArrowFunctionExpression,
|
|
979
954
|
types.AST_NODE_TYPES.FunctionExpression,
|
|
@@ -983,20 +958,69 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
983
958
|
);
|
|
984
959
|
return boundaryNode == null || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
|
|
985
960
|
}
|
|
986
|
-
function
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
if (!isCreateElementCall(context, parent)) return false;
|
|
990
|
-
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
961
|
+
function isComponentWrapperCall(context, node) {
|
|
962
|
+
if (node.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
963
|
+
return isMemoCall(context, node) || isForwardRefCall(context, node);
|
|
991
964
|
}
|
|
992
|
-
function
|
|
993
|
-
|
|
965
|
+
function isComponentWrapperCallLoose(context, node) {
|
|
966
|
+
if (node.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
967
|
+
return isComponentWrapperCall(context, node) || isUseCallbackCall(context, node);
|
|
994
968
|
}
|
|
995
|
-
|
|
996
|
-
|
|
969
|
+
|
|
970
|
+
// src/component/component-id.ts
|
|
971
|
+
function getFunctionComponentId(context, node) {
|
|
972
|
+
const functionId = AST5__namespace.getFunctionIdentifier(node);
|
|
973
|
+
if (functionId != null) {
|
|
974
|
+
return functionId;
|
|
975
|
+
}
|
|
976
|
+
const { parent } = node;
|
|
977
|
+
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCallLoose(context, parent) && parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator && parent.parent.id.type === types.AST_NODE_TYPES.Identifier) {
|
|
978
|
+
return parent.parent.id;
|
|
979
|
+
}
|
|
980
|
+
if (parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCallLoose(context, parent) && parent.parent.type === types.AST_NODE_TYPES.CallExpression && isComponentWrapperCallLoose(context, parent.parent) && parent.parent.parent.type === types.AST_NODE_TYPES.VariableDeclarator && parent.parent.parent.id.type === types.AST_NODE_TYPES.Identifier) {
|
|
981
|
+
return parent.parent.parent.id;
|
|
982
|
+
}
|
|
983
|
+
return eff._;
|
|
997
984
|
}
|
|
998
|
-
|
|
999
|
-
|
|
985
|
+
|
|
986
|
+
// src/component/component-flag.ts
|
|
987
|
+
var ComponentFlag = {
|
|
988
|
+
None: 0n,
|
|
989
|
+
PureComponent: 1n << 0n,
|
|
990
|
+
CreateElement: 1n << 1n,
|
|
991
|
+
Memo: 1n << 2n,
|
|
992
|
+
ForwardRef: 1n << 3n,
|
|
993
|
+
Async: 1n << 4n
|
|
994
|
+
};
|
|
995
|
+
|
|
996
|
+
// src/component/component-init-path.ts
|
|
997
|
+
function getComponentFlagFromInitPath(initPath) {
|
|
998
|
+
let flag = ComponentFlag.None;
|
|
999
|
+
if (initPath != null && AST5__namespace.hasCallInFunctionInitPath("memo", initPath)) {
|
|
1000
|
+
flag |= ComponentFlag.Memo;
|
|
1001
|
+
}
|
|
1002
|
+
if (initPath != null && AST5__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
1003
|
+
flag |= ComponentFlag.ForwardRef;
|
|
1004
|
+
}
|
|
1005
|
+
return flag;
|
|
1006
|
+
}
|
|
1007
|
+
var RE_COMPONENT_NAME = /^[A-Z]/u;
|
|
1008
|
+
var RE_COMPONENT_NAME_LOOSE = /^_?[A-Z]/u;
|
|
1009
|
+
function isComponentName(name) {
|
|
1010
|
+
return RE_COMPONENT_NAME.test(name);
|
|
1011
|
+
}
|
|
1012
|
+
function isComponentNameLoose(name) {
|
|
1013
|
+
return RE_COMPONENT_NAME_LOOSE.test(name);
|
|
1014
|
+
}
|
|
1015
|
+
function getComponentNameFromId(id) {
|
|
1016
|
+
if (id == null) return eff._;
|
|
1017
|
+
return Array.isArray(id) ? id.map((n) => n.name).join(".") : id.name;
|
|
1018
|
+
}
|
|
1019
|
+
function hasNoneOrLooseComponentName(context, fn) {
|
|
1020
|
+
const id = getFunctionComponentId(context, fn);
|
|
1021
|
+
if (id == null) return true;
|
|
1022
|
+
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
1023
|
+
return name != null && isComponentNameLoose(name);
|
|
1000
1024
|
}
|
|
1001
1025
|
|
|
1002
1026
|
// src/component/component-collector.ts
|
|
@@ -1018,7 +1042,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1018
1042
|
const entry = functionEntries.at(-1);
|
|
1019
1043
|
if (entry == null) return;
|
|
1020
1044
|
if (!entry.isComponent) return functionEntries.pop();
|
|
1021
|
-
const shouldDrop =
|
|
1045
|
+
const shouldDrop = AST5__namespace.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
1022
1046
|
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3__namespace.isJSXValue(r.argument, jsxCtx, hint);
|
|
1023
1047
|
});
|
|
1024
1048
|
if (shouldDrop) {
|
|
@@ -1043,9 +1067,9 @@ function useComponentCollector(context, options = {}) {
|
|
|
1043
1067
|
const entry = getCurrentEntry();
|
|
1044
1068
|
if (entry == null) return;
|
|
1045
1069
|
const { body } = entry.node;
|
|
1046
|
-
const isComponent = hasNoneOrLooseComponentName(context, entry.node) && JSX3__namespace.isJSXValue(body, jsxCtx, hint) &&
|
|
1070
|
+
const isComponent = hasNoneOrLooseComponentName(context, entry.node) && JSX3__namespace.isJSXValue(body, jsxCtx, hint) && isValidComponentDefinition(context, entry.node, hint);
|
|
1047
1071
|
if (!isComponent) return;
|
|
1048
|
-
const initPath =
|
|
1072
|
+
const initPath = AST5__namespace.getFunctionInitPath(entry.node);
|
|
1049
1073
|
const id = getFunctionComponentId(context, entry.node);
|
|
1050
1074
|
const name = getComponentNameFromId(id);
|
|
1051
1075
|
const key = shared.getId();
|
|
@@ -1056,7 +1080,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1056
1080
|
name,
|
|
1057
1081
|
node: entry.node,
|
|
1058
1082
|
displayName: eff._,
|
|
1059
|
-
flag:
|
|
1083
|
+
flag: getComponentFlagFromInitPath(initPath),
|
|
1060
1084
|
hint,
|
|
1061
1085
|
hookCalls: entry.hookCalls,
|
|
1062
1086
|
initPath
|
|
@@ -1083,10 +1107,10 @@ function useComponentCollector(context, options = {}) {
|
|
|
1083
1107
|
"ReturnStatement[type]"(node) {
|
|
1084
1108
|
const entry = getCurrentEntry();
|
|
1085
1109
|
if (entry == null) return;
|
|
1086
|
-
const isComponent = hasNoneOrLooseComponentName(context, entry.node) && JSX3__namespace.isJSXValue(node.argument, jsxCtx, hint) &&
|
|
1110
|
+
const isComponent = hasNoneOrLooseComponentName(context, entry.node) && JSX3__namespace.isJSXValue(node.argument, jsxCtx, hint) && isValidComponentDefinition(context, entry.node, hint);
|
|
1087
1111
|
if (!isComponent) return;
|
|
1088
1112
|
entry.isComponent = true;
|
|
1089
|
-
const initPath =
|
|
1113
|
+
const initPath = AST5__namespace.getFunctionInitPath(entry.node);
|
|
1090
1114
|
const id = getFunctionComponentId(context, entry.node);
|
|
1091
1115
|
const name = getComponentNameFromId(id);
|
|
1092
1116
|
components.set(entry.key, {
|
|
@@ -1096,7 +1120,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1096
1120
|
name,
|
|
1097
1121
|
node: entry.node,
|
|
1098
1122
|
displayName: eff._,
|
|
1099
|
-
flag:
|
|
1123
|
+
flag: getComponentFlagFromInitPath(initPath),
|
|
1100
1124
|
hint,
|
|
1101
1125
|
hookCalls: entry.hookCalls,
|
|
1102
1126
|
initPath
|
|
@@ -1105,16 +1129,6 @@ function useComponentCollector(context, options = {}) {
|
|
|
1105
1129
|
};
|
|
1106
1130
|
return { ctx, listeners };
|
|
1107
1131
|
}
|
|
1108
|
-
function getComponentFlag(initPath) {
|
|
1109
|
-
let flag = ComponentFlag.None;
|
|
1110
|
-
if (initPath != null && AST6__namespace.hasCallInFunctionInitPath("memo", initPath)) {
|
|
1111
|
-
flag |= ComponentFlag.Memo;
|
|
1112
|
-
}
|
|
1113
|
-
if (initPath != null && AST6__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
1114
|
-
flag |= ComponentFlag.ForwardRef;
|
|
1115
|
-
}
|
|
1116
|
-
return flag;
|
|
1117
|
-
}
|
|
1118
1132
|
function useComponentCollectorLegacy() {
|
|
1119
1133
|
const components = /* @__PURE__ */ new Map();
|
|
1120
1134
|
const ctx = {
|
|
@@ -1127,7 +1141,7 @@ function useComponentCollectorLegacy() {
|
|
|
1127
1141
|
if (!isClassComponent(node)) {
|
|
1128
1142
|
return;
|
|
1129
1143
|
}
|
|
1130
|
-
const id =
|
|
1144
|
+
const id = AST5__namespace.getClassIdentifier(node);
|
|
1131
1145
|
const key = shared.getId();
|
|
1132
1146
|
const flag = isPureComponent(node) ? ComponentFlag.PureComponent : ComponentFlag.None;
|
|
1133
1147
|
components.set(
|
|
@@ -1160,7 +1174,7 @@ var ComponentPhaseRelevance = birecord__default.default({
|
|
|
1160
1174
|
var isInversePhase = eff.dual(2, (a, b) => ComponentPhaseRelevance.get(a) === b);
|
|
1161
1175
|
function isRenderFunctionLoose(context, node) {
|
|
1162
1176
|
const { body, parent } = node;
|
|
1163
|
-
if (
|
|
1177
|
+
if (AST5__namespace.getFunctionIdentifier(node)?.name.startsWith("render")) {
|
|
1164
1178
|
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");
|
|
1165
1179
|
}
|
|
1166
1180
|
return JSX3__namespace.isJSXValue(
|
|
@@ -1175,7 +1189,7 @@ function isRenderPropLoose(context, node) {
|
|
|
1175
1189
|
if (node.name.type !== types.AST_NODE_TYPES.JSXIdentifier) {
|
|
1176
1190
|
return false;
|
|
1177
1191
|
}
|
|
1178
|
-
return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer &&
|
|
1192
|
+
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);
|
|
1179
1193
|
}
|
|
1180
1194
|
function isDirectValueOfRenderPropertyLoose(node) {
|
|
1181
1195
|
const matching = (node2) => {
|
|
@@ -1187,7 +1201,7 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1187
1201
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
1188
1202
|
return true;
|
|
1189
1203
|
}
|
|
1190
|
-
const parent =
|
|
1204
|
+
const parent = AST5__namespace.findParentNode(node, AST5__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
1191
1205
|
if (parent?.type !== types.AST_NODE_TYPES.JSXAttribute) {
|
|
1192
1206
|
return false;
|
|
1193
1207
|
}
|
|
@@ -1195,11 +1209,11 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1195
1209
|
}
|
|
1196
1210
|
function isThisSetState(node) {
|
|
1197
1211
|
const { callee } = node;
|
|
1198
|
-
return callee.type === types.AST_NODE_TYPES.MemberExpression &&
|
|
1212
|
+
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";
|
|
1199
1213
|
}
|
|
1200
1214
|
function isAssignmentToThisState(node) {
|
|
1201
1215
|
const { left } = node;
|
|
1202
|
-
return left.type === types.AST_NODE_TYPES.MemberExpression &&
|
|
1216
|
+
return left.type === types.AST_NODE_TYPES.MemberExpression && AST5__namespace.isThisExpression(left.object) && AST5__namespace.getPropertyName(left.property) === "state";
|
|
1203
1217
|
}
|
|
1204
1218
|
function isFunctionOfUseEffectSetup(node) {
|
|
1205
1219
|
if (node == null) return false;
|
|
@@ -1207,9 +1221,9 @@ function isFunctionOfUseEffectSetup(node) {
|
|
|
1207
1221
|
}
|
|
1208
1222
|
function isFunctionOfUseEffectCleanup(node) {
|
|
1209
1223
|
if (node == null) return false;
|
|
1210
|
-
const returnStatement =
|
|
1211
|
-
const enclosingFunction =
|
|
1212
|
-
const functionOfReturnStatement =
|
|
1224
|
+
const returnStatement = AST5__namespace.findParentNode(node, AST5__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
|
|
1225
|
+
const enclosingFunction = AST5__namespace.findParentNode(node, AST5__namespace.isFunction);
|
|
1226
|
+
const functionOfReturnStatement = AST5__namespace.findParentNode(returnStatement, AST5__namespace.isFunction);
|
|
1213
1227
|
return enclosingFunction === functionOfReturnStatement && isFunctionOfUseEffectSetup(enclosingFunction);
|
|
1214
1228
|
}
|
|
1215
1229
|
|
|
@@ -1221,11 +1235,11 @@ exports.DISPLAY_NAME_ASSIGNMENT_SELECTOR = DISPLAY_NAME_ASSIGNMENT_SELECTOR;
|
|
|
1221
1235
|
exports.RE_COMPONENT_NAME = RE_COMPONENT_NAME;
|
|
1222
1236
|
exports.RE_COMPONENT_NAME_LOOSE = RE_COMPONENT_NAME_LOOSE;
|
|
1223
1237
|
exports.RE_HOOK_NAME = RE_HOOK_NAME;
|
|
1238
|
+
exports.getComponentFlagFromInitPath = getComponentFlagFromInitPath;
|
|
1224
1239
|
exports.getComponentNameFromId = getComponentNameFromId;
|
|
1225
1240
|
exports.getFunctionComponentId = getFunctionComponentId;
|
|
1226
1241
|
exports.getInstanceId = getInstanceId;
|
|
1227
1242
|
exports.hasNoneOrLooseComponentName = hasNoneOrLooseComponentName;
|
|
1228
|
-
exports.hasValidHierarchy = hasValidHierarchy;
|
|
1229
1243
|
exports.isAssignmentToThisState = isAssignmentToThisState;
|
|
1230
1244
|
exports.isCallFromReact = isCallFromReact;
|
|
1231
1245
|
exports.isCallFromReactObject = isCallFromReactObject;
|
|
@@ -1235,6 +1249,7 @@ exports.isChildrenForEach = isChildrenForEach;
|
|
|
1235
1249
|
exports.isChildrenForEachCall = isChildrenForEachCall;
|
|
1236
1250
|
exports.isChildrenMap = isChildrenMap;
|
|
1237
1251
|
exports.isChildrenMapCall = isChildrenMapCall;
|
|
1252
|
+
exports.isChildrenOfCreateElement = isChildrenOfCreateElement;
|
|
1238
1253
|
exports.isChildrenOnly = isChildrenOnly;
|
|
1239
1254
|
exports.isChildrenOnlyCall = isChildrenOnlyCall;
|
|
1240
1255
|
exports.isChildrenToArray = isChildrenToArray;
|
|
@@ -1247,6 +1262,8 @@ exports.isComponentDidMount = isComponentDidMount;
|
|
|
1247
1262
|
exports.isComponentName = isComponentName;
|
|
1248
1263
|
exports.isComponentNameLoose = isComponentNameLoose;
|
|
1249
1264
|
exports.isComponentWillUnmount = isComponentWillUnmount;
|
|
1265
|
+
exports.isComponentWrapperCall = isComponentWrapperCall;
|
|
1266
|
+
exports.isComponentWrapperCallLoose = isComponentWrapperCallLoose;
|
|
1250
1267
|
exports.isCreateContext = isCreateContext;
|
|
1251
1268
|
exports.isCreateContextCall = isCreateContextCall;
|
|
1252
1269
|
exports.isCreateElement = isCreateElement;
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
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';
|
|
5
5
|
import { AST_NODE_TYPES } from '@typescript-eslint/types';
|
|
6
6
|
import * as VAR from '@eslint-react/var';
|
|
7
|
-
import {
|
|
7
|
+
import { isMatching, P, match } from 'ts-pattern';
|
|
8
8
|
import '@eslint-react/kit';
|
|
9
9
|
import birecord from 'birecord';
|
|
10
10
|
|
|
@@ -533,7 +533,7 @@ function isInitializedFromReact(name, importSource, initialScope) {
|
|
|
533
533
|
}
|
|
534
534
|
const args = getRequireExpressionArguments(init);
|
|
535
535
|
const arg0 = args?.[0];
|
|
536
|
-
if (arg0 == null || !
|
|
536
|
+
if (arg0 == null || !AST5.isKindOfLiteral(arg0, "string")) {
|
|
537
537
|
return false;
|
|
538
538
|
}
|
|
539
539
|
return arg0.value === importSource || arg0.value.startsWith(`${importSource}/`);
|
|
@@ -598,7 +598,7 @@ function isCallFromReactObject(objectName, propertyName) {
|
|
|
598
598
|
});
|
|
599
599
|
}
|
|
600
600
|
function isInstanceIdEqual(context, a, b) {
|
|
601
|
-
return
|
|
601
|
+
return AST5.isNodeEqual(a, b) || VAR.isNodeValueEqual(a, b, [
|
|
602
602
|
context.sourceCode.getScope(a),
|
|
603
603
|
context.sourceCode.getScope(b)
|
|
604
604
|
]);
|
|
@@ -637,7 +637,7 @@ var isMemoCall = isReactAPICall("memo");
|
|
|
637
637
|
// src/hook/is.ts
|
|
638
638
|
function isReactHook(node) {
|
|
639
639
|
if (node == null) return false;
|
|
640
|
-
const id =
|
|
640
|
+
const id = AST5.getFunctionIdentifier(node);
|
|
641
641
|
return id?.name != null && isReactHookName(id.name);
|
|
642
642
|
}
|
|
643
643
|
function isReactHookCall(node) {
|
|
@@ -740,7 +740,7 @@ function useHookCollector() {
|
|
|
740
740
|
const hooks = /* @__PURE__ */ new Map();
|
|
741
741
|
const functionEntries = [];
|
|
742
742
|
const onFunctionEnter = (node) => {
|
|
743
|
-
const id =
|
|
743
|
+
const id = AST5.getFunctionIdentifier(node);
|
|
744
744
|
const key = getId();
|
|
745
745
|
const name = id?.name;
|
|
746
746
|
if (name != null && isReactHookName(name)) {
|
|
@@ -819,54 +819,6 @@ var ComponentCollectorHint = {
|
|
|
819
819
|
SkipClassProperty: 1n << 69n
|
|
820
820
|
};
|
|
821
821
|
var DEFAULT_COMPONENT_HINT = 0n | ComponentCollectorHint.SkipBooleanLiteral | ComponentCollectorHint.SkipEmptyArray | ComponentCollectorHint.SkipArrayMapArgument | ComponentCollectorHint.SkipNumberLiteral | ComponentCollectorHint.SkipStringLiteral | ComponentCollectorHint.SkipUndefined | ComponentCollectorHint.StrictArray | ComponentCollectorHint.StrictConditional | ComponentCollectorHint.StrictLogical;
|
|
822
|
-
|
|
823
|
-
// src/component/component-flag.ts
|
|
824
|
-
var ComponentFlag = {
|
|
825
|
-
None: 0n,
|
|
826
|
-
PureComponent: 1n << 0n,
|
|
827
|
-
CreateElement: 1n << 1n,
|
|
828
|
-
Memo: 1n << 2n,
|
|
829
|
-
ForwardRef: 1n << 3n,
|
|
830
|
-
Async: 1n << 4n
|
|
831
|
-
};
|
|
832
|
-
function isComponentWrapperCall(context, node) {
|
|
833
|
-
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
834
|
-
return false;
|
|
835
|
-
}
|
|
836
|
-
return isMemoCall(context, node) || isForwardRefCall(context, node) || isReactHookCallWithNameLoose(node)("useCallback");
|
|
837
|
-
}
|
|
838
|
-
function getFunctionComponentId(context, node) {
|
|
839
|
-
const functionId = AST6.getFunctionIdentifier(node);
|
|
840
|
-
if (functionId != null) {
|
|
841
|
-
return functionId;
|
|
842
|
-
}
|
|
843
|
-
const { parent } = node;
|
|
844
|
-
if (parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent) && parent.parent.type === AST_NODE_TYPES.VariableDeclarator && parent.parent.id.type === AST_NODE_TYPES.Identifier) {
|
|
845
|
-
return parent.parent.id;
|
|
846
|
-
}
|
|
847
|
-
if (parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent) && parent.parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCall(context, parent.parent) && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator && parent.parent.parent.id.type === AST_NODE_TYPES.Identifier) {
|
|
848
|
-
return parent.parent.parent.id;
|
|
849
|
-
}
|
|
850
|
-
return _;
|
|
851
|
-
}
|
|
852
|
-
var RE_COMPONENT_NAME = /^[A-Z]/u;
|
|
853
|
-
var RE_COMPONENT_NAME_LOOSE = /^_?[A-Z]/u;
|
|
854
|
-
function isComponentName(name) {
|
|
855
|
-
return RE_COMPONENT_NAME.test(name);
|
|
856
|
-
}
|
|
857
|
-
function isComponentNameLoose(name) {
|
|
858
|
-
return RE_COMPONENT_NAME_LOOSE.test(name);
|
|
859
|
-
}
|
|
860
|
-
function getComponentNameFromId(id) {
|
|
861
|
-
if (id == null) return _;
|
|
862
|
-
return Array.isArray(id) ? id.map((n) => n.name).join(".") : id.name;
|
|
863
|
-
}
|
|
864
|
-
function hasNoneOrLooseComponentName(context, fn) {
|
|
865
|
-
const id = getFunctionComponentId(context, fn);
|
|
866
|
-
if (id == null) return true;
|
|
867
|
-
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
868
|
-
return name != null && isComponentNameLoose(name);
|
|
869
|
-
}
|
|
870
822
|
function isClassComponent(node) {
|
|
871
823
|
if ("superClass" in node && node.superClass != null) {
|
|
872
824
|
const re = /^(?:Pure)?Component$/u;
|
|
@@ -894,28 +846,28 @@ function isPureComponent(node) {
|
|
|
894
846
|
|
|
895
847
|
// src/component/component-lifecycle.ts
|
|
896
848
|
function isComponentDidMount(node) {
|
|
897
|
-
return
|
|
849
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
|
|
898
850
|
}
|
|
899
851
|
function isComponentWillUnmount(node) {
|
|
900
|
-
return
|
|
852
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
|
|
901
853
|
}
|
|
902
854
|
function isComponentDidCatch(node) {
|
|
903
|
-
return
|
|
855
|
+
return AST5.isMethodOrProperty(node) && !node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
|
|
904
856
|
}
|
|
905
857
|
function isGetDerivedStateFromError(node) {
|
|
906
|
-
return
|
|
858
|
+
return AST5.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
|
|
907
859
|
}
|
|
908
860
|
function isGetDerivedStateFromProps(node) {
|
|
909
|
-
return
|
|
861
|
+
return AST5.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
|
|
910
862
|
}
|
|
911
863
|
function isFunctionOfComponentDidMount(node) {
|
|
912
|
-
return
|
|
864
|
+
return AST5.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
|
|
913
865
|
}
|
|
914
866
|
function isFunctionOfComponentWillUnmount(node) {
|
|
915
|
-
return
|
|
867
|
+
return AST5.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
|
|
916
868
|
}
|
|
917
869
|
function isRenderMethodLike(node) {
|
|
918
|
-
return
|
|
870
|
+
return AST5.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration;
|
|
919
871
|
}
|
|
920
872
|
function isFunctionOfRenderMethod(node) {
|
|
921
873
|
if (!isRenderMethodLike(node.parent)) {
|
|
@@ -923,12 +875,35 @@ function isFunctionOfRenderMethod(node) {
|
|
|
923
875
|
}
|
|
924
876
|
return isClassComponent(node.parent.parent.parent);
|
|
925
877
|
}
|
|
878
|
+
function isChildrenOfCreateElement(context, node) {
|
|
879
|
+
const parent = node.parent;
|
|
880
|
+
if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
881
|
+
if (!isCreateElementCall(context, parent)) return false;
|
|
882
|
+
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
883
|
+
}
|
|
926
884
|
function isInsideRenderMethod(node) {
|
|
927
|
-
return
|
|
885
|
+
return AST5.findParentNode(node, (n) => isRenderMethodLike(n) && isClassComponent(n.parent.parent)) != null;
|
|
928
886
|
}
|
|
929
887
|
|
|
930
|
-
// src/component/
|
|
931
|
-
|
|
888
|
+
// src/component/component-definition.ts
|
|
889
|
+
var isFunctionOfClassMethod = isMatching({
|
|
890
|
+
type: P.union(AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression),
|
|
891
|
+
parent: AST_NODE_TYPES.MethodDefinition
|
|
892
|
+
});
|
|
893
|
+
var isFunctionOfClassProperty = isMatching({
|
|
894
|
+
type: P.union(AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression),
|
|
895
|
+
parent: AST_NODE_TYPES.Property
|
|
896
|
+
});
|
|
897
|
+
var isFunctionOfObjectMethod = isMatching({
|
|
898
|
+
type: P.union(AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionExpression),
|
|
899
|
+
parent: {
|
|
900
|
+
type: AST_NODE_TYPES.Property,
|
|
901
|
+
parent: {
|
|
902
|
+
type: AST_NODE_TYPES.ObjectExpression
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
function isValidComponentDefinition(context, node, hint) {
|
|
932
907
|
if (isChildrenOfCreateElement(context, node) || isFunctionOfRenderMethod(node)) {
|
|
933
908
|
return false;
|
|
934
909
|
}
|
|
@@ -941,12 +916,12 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
941
916
|
if (hint & ComponentCollectorHint.SkipClassProperty && isFunctionOfClassProperty(node.parent)) {
|
|
942
917
|
return false;
|
|
943
918
|
}
|
|
944
|
-
if (hint & ComponentCollectorHint.SkipArrayMapArgument &&
|
|
919
|
+
if (hint & ComponentCollectorHint.SkipArrayMapArgument && AST5.isArrayMapCallLoose(node.parent)) {
|
|
945
920
|
return false;
|
|
946
921
|
}
|
|
947
|
-
const boundaryNode =
|
|
922
|
+
const boundaryNode = AST5.findParentNode(
|
|
948
923
|
node,
|
|
949
|
-
|
|
924
|
+
AST5.isOneOf([
|
|
950
925
|
AST_NODE_TYPES.JSXExpressionContainer,
|
|
951
926
|
AST_NODE_TYPES.ArrowFunctionExpression,
|
|
952
927
|
AST_NODE_TYPES.FunctionExpression,
|
|
@@ -956,20 +931,69 @@ function hasValidHierarchy(context, node, hint) {
|
|
|
956
931
|
);
|
|
957
932
|
return boundaryNode == null || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
|
|
958
933
|
}
|
|
959
|
-
function
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
if (!isCreateElementCall(context, parent)) return false;
|
|
963
|
-
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
934
|
+
function isComponentWrapperCall(context, node) {
|
|
935
|
+
if (node.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
936
|
+
return isMemoCall(context, node) || isForwardRefCall(context, node);
|
|
964
937
|
}
|
|
965
|
-
function
|
|
966
|
-
|
|
938
|
+
function isComponentWrapperCallLoose(context, node) {
|
|
939
|
+
if (node.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
940
|
+
return isComponentWrapperCall(context, node) || isUseCallbackCall(context, node);
|
|
967
941
|
}
|
|
968
|
-
|
|
969
|
-
|
|
942
|
+
|
|
943
|
+
// src/component/component-id.ts
|
|
944
|
+
function getFunctionComponentId(context, node) {
|
|
945
|
+
const functionId = AST5.getFunctionIdentifier(node);
|
|
946
|
+
if (functionId != null) {
|
|
947
|
+
return functionId;
|
|
948
|
+
}
|
|
949
|
+
const { parent } = node;
|
|
950
|
+
if (parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCallLoose(context, parent) && parent.parent.type === AST_NODE_TYPES.VariableDeclarator && parent.parent.id.type === AST_NODE_TYPES.Identifier) {
|
|
951
|
+
return parent.parent.id;
|
|
952
|
+
}
|
|
953
|
+
if (parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCallLoose(context, parent) && parent.parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCallLoose(context, parent.parent) && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator && parent.parent.parent.id.type === AST_NODE_TYPES.Identifier) {
|
|
954
|
+
return parent.parent.parent.id;
|
|
955
|
+
}
|
|
956
|
+
return _;
|
|
970
957
|
}
|
|
971
|
-
|
|
972
|
-
|
|
958
|
+
|
|
959
|
+
// src/component/component-flag.ts
|
|
960
|
+
var ComponentFlag = {
|
|
961
|
+
None: 0n,
|
|
962
|
+
PureComponent: 1n << 0n,
|
|
963
|
+
CreateElement: 1n << 1n,
|
|
964
|
+
Memo: 1n << 2n,
|
|
965
|
+
ForwardRef: 1n << 3n,
|
|
966
|
+
Async: 1n << 4n
|
|
967
|
+
};
|
|
968
|
+
|
|
969
|
+
// src/component/component-init-path.ts
|
|
970
|
+
function getComponentFlagFromInitPath(initPath) {
|
|
971
|
+
let flag = ComponentFlag.None;
|
|
972
|
+
if (initPath != null && AST5.hasCallInFunctionInitPath("memo", initPath)) {
|
|
973
|
+
flag |= ComponentFlag.Memo;
|
|
974
|
+
}
|
|
975
|
+
if (initPath != null && AST5.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
976
|
+
flag |= ComponentFlag.ForwardRef;
|
|
977
|
+
}
|
|
978
|
+
return flag;
|
|
979
|
+
}
|
|
980
|
+
var RE_COMPONENT_NAME = /^[A-Z]/u;
|
|
981
|
+
var RE_COMPONENT_NAME_LOOSE = /^_?[A-Z]/u;
|
|
982
|
+
function isComponentName(name) {
|
|
983
|
+
return RE_COMPONENT_NAME.test(name);
|
|
984
|
+
}
|
|
985
|
+
function isComponentNameLoose(name) {
|
|
986
|
+
return RE_COMPONENT_NAME_LOOSE.test(name);
|
|
987
|
+
}
|
|
988
|
+
function getComponentNameFromId(id) {
|
|
989
|
+
if (id == null) return _;
|
|
990
|
+
return Array.isArray(id) ? id.map((n) => n.name).join(".") : id.name;
|
|
991
|
+
}
|
|
992
|
+
function hasNoneOrLooseComponentName(context, fn) {
|
|
993
|
+
const id = getFunctionComponentId(context, fn);
|
|
994
|
+
if (id == null) return true;
|
|
995
|
+
const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
|
|
996
|
+
return name != null && isComponentNameLoose(name);
|
|
973
997
|
}
|
|
974
998
|
|
|
975
999
|
// src/component/component-collector.ts
|
|
@@ -991,7 +1015,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
991
1015
|
const entry = functionEntries.at(-1);
|
|
992
1016
|
if (entry == null) return;
|
|
993
1017
|
if (!entry.isComponent) return functionEntries.pop();
|
|
994
|
-
const shouldDrop =
|
|
1018
|
+
const shouldDrop = AST5.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
995
1019
|
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3.isJSXValue(r.argument, jsxCtx, hint);
|
|
996
1020
|
});
|
|
997
1021
|
if (shouldDrop) {
|
|
@@ -1016,9 +1040,9 @@ function useComponentCollector(context, options = {}) {
|
|
|
1016
1040
|
const entry = getCurrentEntry();
|
|
1017
1041
|
if (entry == null) return;
|
|
1018
1042
|
const { body } = entry.node;
|
|
1019
|
-
const isComponent = hasNoneOrLooseComponentName(context, entry.node) && JSX3.isJSXValue(body, jsxCtx, hint) &&
|
|
1043
|
+
const isComponent = hasNoneOrLooseComponentName(context, entry.node) && JSX3.isJSXValue(body, jsxCtx, hint) && isValidComponentDefinition(context, entry.node, hint);
|
|
1020
1044
|
if (!isComponent) return;
|
|
1021
|
-
const initPath =
|
|
1045
|
+
const initPath = AST5.getFunctionInitPath(entry.node);
|
|
1022
1046
|
const id = getFunctionComponentId(context, entry.node);
|
|
1023
1047
|
const name = getComponentNameFromId(id);
|
|
1024
1048
|
const key = getId();
|
|
@@ -1029,7 +1053,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1029
1053
|
name,
|
|
1030
1054
|
node: entry.node,
|
|
1031
1055
|
displayName: _,
|
|
1032
|
-
flag:
|
|
1056
|
+
flag: getComponentFlagFromInitPath(initPath),
|
|
1033
1057
|
hint,
|
|
1034
1058
|
hookCalls: entry.hookCalls,
|
|
1035
1059
|
initPath
|
|
@@ -1056,10 +1080,10 @@ function useComponentCollector(context, options = {}) {
|
|
|
1056
1080
|
"ReturnStatement[type]"(node) {
|
|
1057
1081
|
const entry = getCurrentEntry();
|
|
1058
1082
|
if (entry == null) return;
|
|
1059
|
-
const isComponent = hasNoneOrLooseComponentName(context, entry.node) && JSX3.isJSXValue(node.argument, jsxCtx, hint) &&
|
|
1083
|
+
const isComponent = hasNoneOrLooseComponentName(context, entry.node) && JSX3.isJSXValue(node.argument, jsxCtx, hint) && isValidComponentDefinition(context, entry.node, hint);
|
|
1060
1084
|
if (!isComponent) return;
|
|
1061
1085
|
entry.isComponent = true;
|
|
1062
|
-
const initPath =
|
|
1086
|
+
const initPath = AST5.getFunctionInitPath(entry.node);
|
|
1063
1087
|
const id = getFunctionComponentId(context, entry.node);
|
|
1064
1088
|
const name = getComponentNameFromId(id);
|
|
1065
1089
|
components.set(entry.key, {
|
|
@@ -1069,7 +1093,7 @@ function useComponentCollector(context, options = {}) {
|
|
|
1069
1093
|
name,
|
|
1070
1094
|
node: entry.node,
|
|
1071
1095
|
displayName: _,
|
|
1072
|
-
flag:
|
|
1096
|
+
flag: getComponentFlagFromInitPath(initPath),
|
|
1073
1097
|
hint,
|
|
1074
1098
|
hookCalls: entry.hookCalls,
|
|
1075
1099
|
initPath
|
|
@@ -1078,16 +1102,6 @@ function useComponentCollector(context, options = {}) {
|
|
|
1078
1102
|
};
|
|
1079
1103
|
return { ctx, listeners };
|
|
1080
1104
|
}
|
|
1081
|
-
function getComponentFlag(initPath) {
|
|
1082
|
-
let flag = ComponentFlag.None;
|
|
1083
|
-
if (initPath != null && AST6.hasCallInFunctionInitPath("memo", initPath)) {
|
|
1084
|
-
flag |= ComponentFlag.Memo;
|
|
1085
|
-
}
|
|
1086
|
-
if (initPath != null && AST6.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
1087
|
-
flag |= ComponentFlag.ForwardRef;
|
|
1088
|
-
}
|
|
1089
|
-
return flag;
|
|
1090
|
-
}
|
|
1091
1105
|
function useComponentCollectorLegacy() {
|
|
1092
1106
|
const components = /* @__PURE__ */ new Map();
|
|
1093
1107
|
const ctx = {
|
|
@@ -1100,7 +1114,7 @@ function useComponentCollectorLegacy() {
|
|
|
1100
1114
|
if (!isClassComponent(node)) {
|
|
1101
1115
|
return;
|
|
1102
1116
|
}
|
|
1103
|
-
const id =
|
|
1117
|
+
const id = AST5.getClassIdentifier(node);
|
|
1104
1118
|
const key = getId();
|
|
1105
1119
|
const flag = isPureComponent(node) ? ComponentFlag.PureComponent : ComponentFlag.None;
|
|
1106
1120
|
components.set(
|
|
@@ -1133,7 +1147,7 @@ var ComponentPhaseRelevance = birecord({
|
|
|
1133
1147
|
var isInversePhase = dual(2, (a, b) => ComponentPhaseRelevance.get(a) === b);
|
|
1134
1148
|
function isRenderFunctionLoose(context, node) {
|
|
1135
1149
|
const { body, parent } = node;
|
|
1136
|
-
if (
|
|
1150
|
+
if (AST5.getFunctionIdentifier(node)?.name.startsWith("render")) {
|
|
1137
1151
|
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");
|
|
1138
1152
|
}
|
|
1139
1153
|
return JSX3.isJSXValue(
|
|
@@ -1148,7 +1162,7 @@ function isRenderPropLoose(context, node) {
|
|
|
1148
1162
|
if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) {
|
|
1149
1163
|
return false;
|
|
1150
1164
|
}
|
|
1151
|
-
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer &&
|
|
1165
|
+
return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && AST5.isFunction(node.value.expression) && isRenderFunctionLoose(context, node.value.expression);
|
|
1152
1166
|
}
|
|
1153
1167
|
function isDirectValueOfRenderPropertyLoose(node) {
|
|
1154
1168
|
const matching = (node2) => {
|
|
@@ -1160,7 +1174,7 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1160
1174
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
1161
1175
|
return true;
|
|
1162
1176
|
}
|
|
1163
|
-
const parent =
|
|
1177
|
+
const parent = AST5.findParentNode(node, AST5.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
1164
1178
|
if (parent?.type !== AST_NODE_TYPES.JSXAttribute) {
|
|
1165
1179
|
return false;
|
|
1166
1180
|
}
|
|
@@ -1168,11 +1182,11 @@ function isDeclaredInRenderPropLoose(node) {
|
|
|
1168
1182
|
}
|
|
1169
1183
|
function isThisSetState(node) {
|
|
1170
1184
|
const { callee } = node;
|
|
1171
|
-
return callee.type === AST_NODE_TYPES.MemberExpression &&
|
|
1185
|
+
return callee.type === AST_NODE_TYPES.MemberExpression && AST5.isThisExpression(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
1172
1186
|
}
|
|
1173
1187
|
function isAssignmentToThisState(node) {
|
|
1174
1188
|
const { left } = node;
|
|
1175
|
-
return left.type === AST_NODE_TYPES.MemberExpression &&
|
|
1189
|
+
return left.type === AST_NODE_TYPES.MemberExpression && AST5.isThisExpression(left.object) && AST5.getPropertyName(left.property) === "state";
|
|
1176
1190
|
}
|
|
1177
1191
|
function isFunctionOfUseEffectSetup(node) {
|
|
1178
1192
|
if (node == null) return false;
|
|
@@ -1180,10 +1194,10 @@ function isFunctionOfUseEffectSetup(node) {
|
|
|
1180
1194
|
}
|
|
1181
1195
|
function isFunctionOfUseEffectCleanup(node) {
|
|
1182
1196
|
if (node == null) return false;
|
|
1183
|
-
const returnStatement =
|
|
1184
|
-
const enclosingFunction =
|
|
1185
|
-
const functionOfReturnStatement =
|
|
1197
|
+
const returnStatement = AST5.findParentNode(node, AST5.is(AST_NODE_TYPES.ReturnStatement));
|
|
1198
|
+
const enclosingFunction = AST5.findParentNode(node, AST5.isFunction);
|
|
1199
|
+
const functionOfReturnStatement = AST5.findParentNode(returnStatement, AST5.isFunction);
|
|
1186
1200
|
return enclosingFunction === functionOfReturnStatement && isFunctionOfUseEffectSetup(enclosingFunction);
|
|
1187
1201
|
}
|
|
1188
1202
|
|
|
1189
|
-
export { ComponentCollectorHint, ComponentFlag, ComponentPhaseRelevance, DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, RE_COMPONENT_NAME, RE_COMPONENT_NAME_LOOSE, RE_HOOK_NAME, getComponentNameFromId, getFunctionComponentId, getInstanceId, hasNoneOrLooseComponentName,
|
|
1203
|
+
export { ComponentCollectorHint, ComponentFlag, ComponentPhaseRelevance, DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, RE_COMPONENT_NAME, RE_COMPONENT_NAME_LOOSE, RE_HOOK_NAME, getComponentFlagFromInitPath, getComponentNameFromId, getFunctionComponentId, getInstanceId, hasNoneOrLooseComponentName, isAssignmentToThisState, isCallFromReact, isCallFromReactObject, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentNameLoose, isComponentWillUnmount, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactObject, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideRenderMethod, isInstanceIdEqual, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isReactHookNameLoose, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, 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.39.0-beta.
|
|
3
|
+
"version": "1.39.0-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,12 +41,12 @@
|
|
|
41
41
|
"@typescript-eslint/utils": "^8.28.0",
|
|
42
42
|
"birecord": "^0.1.1",
|
|
43
43
|
"ts-pattern": "^5.7.0",
|
|
44
|
-
"@eslint-react/ast": "1.39.0-beta.
|
|
45
|
-
"@eslint-react/eff": "1.39.0-beta.
|
|
46
|
-
"@eslint-react/
|
|
47
|
-
"@eslint-react/
|
|
48
|
-
"@eslint-react/var": "1.39.0-beta.
|
|
49
|
-
"@eslint-react/
|
|
44
|
+
"@eslint-react/ast": "1.39.0-beta.2",
|
|
45
|
+
"@eslint-react/eff": "1.39.0-beta.2",
|
|
46
|
+
"@eslint-react/jsx": "1.39.0-beta.2",
|
|
47
|
+
"@eslint-react/kit": "1.39.0-beta.2",
|
|
48
|
+
"@eslint-react/var": "1.39.0-beta.2",
|
|
49
|
+
"@eslint-react/shared": "1.39.0-beta.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"tsup": "^8.4.0",
|