@eslint-react/core 1.24.0-beta.0 → 1.24.0-beta.3
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 +13 -9
- package/dist/index.d.ts +13 -9
- package/dist/index.js +67 -72
- package/dist/index.mjs +67 -72
- package/package.json +7 -7
package/dist/index.d.mts
CHANGED
|
@@ -11,8 +11,8 @@ import { Scope } from '@typescript-eslint/scope-manager';
|
|
|
11
11
|
import { SyntaxKind } from 'typescript';
|
|
12
12
|
|
|
13
13
|
interface ERSemanticNode {
|
|
14
|
-
_: string;
|
|
15
14
|
id: _ | TSESTree.Identifier | TSESTree.Identifier[];
|
|
15
|
+
key: string;
|
|
16
16
|
kind: string;
|
|
17
17
|
name: _ | string;
|
|
18
18
|
node: TSESTree.Node;
|
|
@@ -79,7 +79,11 @@ interface ERClassComponent extends ERSemanticNode {
|
|
|
79
79
|
}
|
|
80
80
|
type ERComponent = ERClassComponent | ERFunctionComponent;
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
interface ComponentCollectorOptions {
|
|
83
|
+
collectDisplayName?: boolean;
|
|
84
|
+
collectHookCalls?: boolean;
|
|
85
|
+
}
|
|
86
|
+
declare function useComponentCollector(context: RuleContext, hint?: bigint, options?: ComponentCollectorOptions): {
|
|
83
87
|
readonly ctx: {
|
|
84
88
|
readonly getAllComponents: (node: TSESTree.Program) => Map<string, ERFunctionComponent>;
|
|
85
89
|
readonly getCurrentEntries: () => {
|
|
@@ -96,6 +100,11 @@ declare function useComponentCollector(context: RuleContext, hint?: bigint): {
|
|
|
96
100
|
} | undefined;
|
|
97
101
|
};
|
|
98
102
|
readonly listeners: {
|
|
103
|
+
readonly "ReturnStatement[type]": (node: TSESTree.ReturnStatement) => void;
|
|
104
|
+
readonly "CallExpression[type]:exit"?: (node: TSESTree.CallExpression) => void;
|
|
105
|
+
readonly "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']"?: (node: TSESTree.AssignmentExpression & {
|
|
106
|
+
left: TSESTree.MemberExpression;
|
|
107
|
+
}) => void;
|
|
99
108
|
readonly ":function[type]": (node: AST.TSESTreeFunction) => void;
|
|
100
109
|
readonly ":function[type]:exit": () => {
|
|
101
110
|
key: string;
|
|
@@ -104,11 +113,6 @@ declare function useComponentCollector(context: RuleContext, hint?: bigint): {
|
|
|
104
113
|
isComponent: boolean;
|
|
105
114
|
} | undefined;
|
|
106
115
|
readonly "ArrowFunctionExpression[type][body.type!='BlockStatement']": () => void;
|
|
107
|
-
readonly "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']": (node: TSESTree.AssignmentExpression & {
|
|
108
|
-
left: TSESTree.MemberExpression;
|
|
109
|
-
}) => void;
|
|
110
|
-
readonly "CallExpression[type]:exit": (node: TSESTree.CallExpression) => void;
|
|
111
|
-
readonly "ReturnStatement[type]": (node: TSESTree.ReturnStatement) => void;
|
|
112
116
|
};
|
|
113
117
|
};
|
|
114
118
|
|
|
@@ -130,7 +134,7 @@ type EREffectMethodKind = "useEffect" | "useInsertionEffect" | "useLayoutEffect"
|
|
|
130
134
|
type ERLifecycleMethodKind = "componentDidMount" | "componentWillUnmount";
|
|
131
135
|
|
|
132
136
|
declare const RE_COMPONENT_NAME: RegExp;
|
|
133
|
-
declare function getComponentNameFromIdentifier(node: TSESTree.Identifier | TSESTree.Identifier[]): string;
|
|
137
|
+
declare function getComponentNameFromIdentifier(node: TSESTree.Identifier | TSESTree.Identifier[] | _): string | undefined;
|
|
134
138
|
declare function isComponentName(name: string): boolean;
|
|
135
139
|
|
|
136
140
|
declare function isRenderMethodLike(node: TSESTree$1.Node): node is TSESTree$1.MethodDefinition | TSESTree$1.PropertyDefinition;
|
|
@@ -2575,4 +2579,4 @@ declare const isMemoCall: {
|
|
|
2575
2579
|
(node: Node, context: _eslint_react_types.RuleContext): node is CallExpression;
|
|
2576
2580
|
};
|
|
2577
2581
|
|
|
2578
|
-
export { DEFAULT_COMPONENT_HINT, type ERClassComponent, ERClassComponentFlag, type ERComponent, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectMethodKind, type EREffectPhaseKind, type ERFunctionComponent, ERFunctionComponentFlag, type ERHook, type ERHookKind, type ERLifecycleMethodKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getElementNameAndRepresentName, getFunctionComponentIdentifier, getId, hasNoneOrValidComponentName, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCleanupFunction, isCloneElement, isCloneElementCall, isComponentDidMount, isComponentDidMountFunction, isComponentName, isComponentWillUnmount, isComponentWillUnmountFunction, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactMember, isFunctionOfRenderMethod, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isSetupFunction, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
|
2582
|
+
export { type ComponentCollectorOptions, DEFAULT_COMPONENT_HINT, type ERClassComponent, ERClassComponentFlag, type ERComponent, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectMethodKind, type EREffectPhaseKind, type ERFunctionComponent, ERFunctionComponentFlag, type ERHook, type ERHookKind, type ERLifecycleMethodKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getElementNameAndRepresentName, getFunctionComponentIdentifier, getId, hasNoneOrValidComponentName, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCleanupFunction, isCloneElement, isCloneElementCall, isComponentDidMount, isComponentDidMountFunction, isComponentName, isComponentWillUnmount, isComponentWillUnmountFunction, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactMember, isFunctionOfRenderMethod, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isSetupFunction, 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
|
@@ -11,8 +11,8 @@ import { Scope } from '@typescript-eslint/scope-manager';
|
|
|
11
11
|
import { SyntaxKind } from 'typescript';
|
|
12
12
|
|
|
13
13
|
interface ERSemanticNode {
|
|
14
|
-
_: string;
|
|
15
14
|
id: _ | TSESTree.Identifier | TSESTree.Identifier[];
|
|
15
|
+
key: string;
|
|
16
16
|
kind: string;
|
|
17
17
|
name: _ | string;
|
|
18
18
|
node: TSESTree.Node;
|
|
@@ -79,7 +79,11 @@ interface ERClassComponent extends ERSemanticNode {
|
|
|
79
79
|
}
|
|
80
80
|
type ERComponent = ERClassComponent | ERFunctionComponent;
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
interface ComponentCollectorOptions {
|
|
83
|
+
collectDisplayName?: boolean;
|
|
84
|
+
collectHookCalls?: boolean;
|
|
85
|
+
}
|
|
86
|
+
declare function useComponentCollector(context: RuleContext, hint?: bigint, options?: ComponentCollectorOptions): {
|
|
83
87
|
readonly ctx: {
|
|
84
88
|
readonly getAllComponents: (node: TSESTree.Program) => Map<string, ERFunctionComponent>;
|
|
85
89
|
readonly getCurrentEntries: () => {
|
|
@@ -96,6 +100,11 @@ declare function useComponentCollector(context: RuleContext, hint?: bigint): {
|
|
|
96
100
|
} | undefined;
|
|
97
101
|
};
|
|
98
102
|
readonly listeners: {
|
|
103
|
+
readonly "ReturnStatement[type]": (node: TSESTree.ReturnStatement) => void;
|
|
104
|
+
readonly "CallExpression[type]:exit"?: (node: TSESTree.CallExpression) => void;
|
|
105
|
+
readonly "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']"?: (node: TSESTree.AssignmentExpression & {
|
|
106
|
+
left: TSESTree.MemberExpression;
|
|
107
|
+
}) => void;
|
|
99
108
|
readonly ":function[type]": (node: AST.TSESTreeFunction) => void;
|
|
100
109
|
readonly ":function[type]:exit": () => {
|
|
101
110
|
key: string;
|
|
@@ -104,11 +113,6 @@ declare function useComponentCollector(context: RuleContext, hint?: bigint): {
|
|
|
104
113
|
isComponent: boolean;
|
|
105
114
|
} | undefined;
|
|
106
115
|
readonly "ArrowFunctionExpression[type][body.type!='BlockStatement']": () => void;
|
|
107
|
-
readonly "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']": (node: TSESTree.AssignmentExpression & {
|
|
108
|
-
left: TSESTree.MemberExpression;
|
|
109
|
-
}) => void;
|
|
110
|
-
readonly "CallExpression[type]:exit": (node: TSESTree.CallExpression) => void;
|
|
111
|
-
readonly "ReturnStatement[type]": (node: TSESTree.ReturnStatement) => void;
|
|
112
116
|
};
|
|
113
117
|
};
|
|
114
118
|
|
|
@@ -130,7 +134,7 @@ type EREffectMethodKind = "useEffect" | "useInsertionEffect" | "useLayoutEffect"
|
|
|
130
134
|
type ERLifecycleMethodKind = "componentDidMount" | "componentWillUnmount";
|
|
131
135
|
|
|
132
136
|
declare const RE_COMPONENT_NAME: RegExp;
|
|
133
|
-
declare function getComponentNameFromIdentifier(node: TSESTree.Identifier | TSESTree.Identifier[]): string;
|
|
137
|
+
declare function getComponentNameFromIdentifier(node: TSESTree.Identifier | TSESTree.Identifier[] | _): string | undefined;
|
|
134
138
|
declare function isComponentName(name: string): boolean;
|
|
135
139
|
|
|
136
140
|
declare function isRenderMethodLike(node: TSESTree$1.Node): node is TSESTree$1.MethodDefinition | TSESTree$1.PropertyDefinition;
|
|
@@ -2575,4 +2579,4 @@ declare const isMemoCall: {
|
|
|
2575
2579
|
(node: Node, context: _eslint_react_types.RuleContext): node is CallExpression;
|
|
2576
2580
|
};
|
|
2577
2581
|
|
|
2578
|
-
export { DEFAULT_COMPONENT_HINT, type ERClassComponent, ERClassComponentFlag, type ERComponent, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectMethodKind, type EREffectPhaseKind, type ERFunctionComponent, ERFunctionComponentFlag, type ERHook, type ERHookKind, type ERLifecycleMethodKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getElementNameAndRepresentName, getFunctionComponentIdentifier, getId, hasNoneOrValidComponentName, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCleanupFunction, isCloneElement, isCloneElementCall, isComponentDidMount, isComponentDidMountFunction, isComponentName, isComponentWillUnmount, isComponentWillUnmountFunction, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactMember, isFunctionOfRenderMethod, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isSetupFunction, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
|
|
2582
|
+
export { type ComponentCollectorOptions, DEFAULT_COMPONENT_HINT, type ERClassComponent, ERClassComponentFlag, type ERComponent, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectMethodKind, type EREffectPhaseKind, type ERFunctionComponent, ERFunctionComponentFlag, type ERHook, type ERHookKind, type ERLifecycleMethodKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getElementNameAndRepresentName, getFunctionComponentIdentifier, getId, hasNoneOrValidComponentName, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCleanupFunction, isCloneElement, isCloneElementCall, isComponentDidMount, isComponentDidMountFunction, isComponentName, isComponentWillUnmount, isComponentWillUnmountFunction, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFromReact, isFromReactMember, isFunctionOfRenderMethod, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isSetupFunction, 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
|
@@ -34,7 +34,7 @@ function getElementNameAndRepresentName(node, context, polymorphicPropName, addi
|
|
|
34
34
|
const name = JSX4__namespace.getElementName(node);
|
|
35
35
|
if (name === name.toLowerCase()) return [name, name];
|
|
36
36
|
const component = additionalComponents.findLast((c) => c.name === name || c.re.test(name));
|
|
37
|
-
if (component
|
|
37
|
+
if (component != null) return [name, component.as];
|
|
38
38
|
if (polymorphicPropName == null) return [name, name];
|
|
39
39
|
const initialScope = context.sourceCode.getScope(node);
|
|
40
40
|
const polymorphicProp = JSX4__namespace.findPropInAttributes(
|
|
@@ -42,7 +42,7 @@ function getElementNameAndRepresentName(node, context, polymorphicPropName, addi
|
|
|
42
42
|
initialScope,
|
|
43
43
|
node.attributes
|
|
44
44
|
);
|
|
45
|
-
if (polymorphicProp
|
|
45
|
+
if (polymorphicProp == null) return [name, name];
|
|
46
46
|
const polymorphicName = VAR__namespace.toResolved(JSX4__namespace.getPropValue(polymorphicProp, initialScope)).value;
|
|
47
47
|
if (typeof polymorphicName === "string") {
|
|
48
48
|
return [name, polymorphicName];
|
|
@@ -164,15 +164,15 @@ var isMemoCall = isReactAPICallWithName("memo");
|
|
|
164
164
|
|
|
165
165
|
// src/element/hierarchy.ts
|
|
166
166
|
function isInsideCreateElementProps(node, context) {
|
|
167
|
-
const call = AST8__namespace.
|
|
168
|
-
if (
|
|
169
|
-
const prop = AST8__namespace.
|
|
170
|
-
if (
|
|
167
|
+
const call = AST8__namespace.findParentNode(node, isCreateElementCall(context));
|
|
168
|
+
if (call == null) return false;
|
|
169
|
+
const prop = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.ObjectExpression));
|
|
170
|
+
if (prop == null) return false;
|
|
171
171
|
return prop === call.arguments[1];
|
|
172
172
|
}
|
|
173
173
|
function isChildrenOfCreateElement(node, context) {
|
|
174
174
|
const parent = node.parent;
|
|
175
|
-
if (
|
|
175
|
+
if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
|
|
176
176
|
if (!isCreateElementCall(parent, context)) return false;
|
|
177
177
|
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
178
178
|
}
|
|
@@ -185,12 +185,12 @@ function isReactHookName(name) {
|
|
|
185
185
|
|
|
186
186
|
// src/hook/is.ts
|
|
187
187
|
function isReactHook(node) {
|
|
188
|
-
if (node
|
|
188
|
+
if (node == null) return eff._;
|
|
189
189
|
const id2 = AST8__namespace.getFunctionIdentifier(node);
|
|
190
|
-
return id2?.name
|
|
190
|
+
return id2?.name != null && isReactHookName(id2.name);
|
|
191
191
|
}
|
|
192
192
|
function isReactHookCall(node) {
|
|
193
|
-
if (node
|
|
193
|
+
if (node == null) return false;
|
|
194
194
|
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
195
195
|
return false;
|
|
196
196
|
}
|
|
@@ -203,7 +203,7 @@ function isReactHookCall(node) {
|
|
|
203
203
|
return false;
|
|
204
204
|
}
|
|
205
205
|
function isReactHookCallWithName(node, context) {
|
|
206
|
-
if (node
|
|
206
|
+
if (node == null) return eff.returnFalse;
|
|
207
207
|
const settings = shared.unsafeDecodeSettings(context.settings);
|
|
208
208
|
return (name) => {
|
|
209
209
|
const initialScope = context.sourceCode.getScope(node);
|
|
@@ -218,7 +218,7 @@ function isReactHookCallWithName(node, context) {
|
|
|
218
218
|
};
|
|
219
219
|
}
|
|
220
220
|
function isReactHookCallWithNameLoose(node) {
|
|
221
|
-
if (node
|
|
221
|
+
if (node == null) return eff.returnFalse;
|
|
222
222
|
return (name) => {
|
|
223
223
|
switch (node.callee.type) {
|
|
224
224
|
case types.AST_NODE_TYPES.Identifier:
|
|
@@ -245,7 +245,7 @@ function isReactHookCallWithNameAlias(name, context, alias) {
|
|
|
245
245
|
};
|
|
246
246
|
}
|
|
247
247
|
function isUseEffectCallLoose(node) {
|
|
248
|
-
if (node
|
|
248
|
+
if (node == null) return false;
|
|
249
249
|
if (node.type !== types.AST_NODE_TYPES.CallExpression) {
|
|
250
250
|
return false;
|
|
251
251
|
}
|
|
@@ -276,7 +276,7 @@ var isUseTransitionCall = eff.flip(isReactHookCallWithName)("useTransition");
|
|
|
276
276
|
|
|
277
277
|
// src/hook/hierarchy.ts
|
|
278
278
|
function isInsideReactHook(node) {
|
|
279
|
-
return isReactHook(AST8__namespace.
|
|
279
|
+
return isReactHook(AST8__namespace.findParentNode(node, AST8__namespace.isFunction));
|
|
280
280
|
}
|
|
281
281
|
function useHookCollector() {
|
|
282
282
|
const hooks = /* @__PURE__ */ new Map();
|
|
@@ -284,12 +284,12 @@ function useHookCollector() {
|
|
|
284
284
|
const onFunctionEnter = (node) => {
|
|
285
285
|
const id2 = AST8__namespace.getFunctionIdentifier(node);
|
|
286
286
|
const name = id2?.name;
|
|
287
|
-
if (name
|
|
287
|
+
if (name != null && isReactHookName(name)) {
|
|
288
288
|
const key = getId();
|
|
289
289
|
fEntries.push({ key, node });
|
|
290
290
|
hooks.set(key, {
|
|
291
|
-
_: key,
|
|
292
291
|
id: id2,
|
|
292
|
+
key,
|
|
293
293
|
kind: "function",
|
|
294
294
|
name,
|
|
295
295
|
node,
|
|
@@ -321,20 +321,14 @@ function useHookCollector() {
|
|
|
321
321
|
return;
|
|
322
322
|
}
|
|
323
323
|
const fEntry = fEntries.at(-1);
|
|
324
|
-
if (fEntry?.key
|
|
324
|
+
if (fEntry?.key == null) {
|
|
325
325
|
return;
|
|
326
326
|
}
|
|
327
327
|
const hook = hooks.get(fEntry.key);
|
|
328
|
-
if (hook
|
|
328
|
+
if (hook == null) {
|
|
329
329
|
return;
|
|
330
330
|
}
|
|
331
|
-
|
|
332
|
-
...hook,
|
|
333
|
-
hookCalls: [
|
|
334
|
-
...hook.hookCalls,
|
|
335
|
-
node
|
|
336
|
-
]
|
|
337
|
-
});
|
|
331
|
+
hook.hookCalls.push(node);
|
|
338
332
|
}
|
|
339
333
|
};
|
|
340
334
|
return { ctx, listeners };
|
|
@@ -383,7 +377,7 @@ function isComponentWrapperCall(node, context) {
|
|
|
383
377
|
}
|
|
384
378
|
function getFunctionComponentIdentifier(node, context) {
|
|
385
379
|
const functionId = AST8__namespace.getFunctionIdentifier(node);
|
|
386
|
-
if (functionId) {
|
|
380
|
+
if (functionId != null) {
|
|
387
381
|
return functionId;
|
|
388
382
|
}
|
|
389
383
|
const { parent } = node;
|
|
@@ -395,17 +389,16 @@ function getFunctionComponentIdentifier(node, context) {
|
|
|
395
389
|
}
|
|
396
390
|
return eff._;
|
|
397
391
|
}
|
|
398
|
-
|
|
399
|
-
// src/component/component-name.ts
|
|
400
392
|
var RE_COMPONENT_NAME = /^_?[A-Z]/u;
|
|
401
393
|
function getComponentNameFromIdentifier(node) {
|
|
394
|
+
if (node == null) return eff._;
|
|
402
395
|
return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
|
|
403
396
|
}
|
|
404
397
|
function isComponentName(name) {
|
|
405
398
|
return RE_COMPONENT_NAME.test(name);
|
|
406
399
|
}
|
|
407
400
|
function isClassComponent(node) {
|
|
408
|
-
if ("superClass" in node && node.superClass) {
|
|
401
|
+
if ("superClass" in node && node.superClass != null) {
|
|
409
402
|
const re = /^(?:Pure)?Component$/u;
|
|
410
403
|
switch (true) {
|
|
411
404
|
case node.superClass.type === types.AST_NODE_TYPES.Identifier:
|
|
@@ -417,7 +410,7 @@ function isClassComponent(node) {
|
|
|
417
410
|
return false;
|
|
418
411
|
}
|
|
419
412
|
function isPureComponent(node) {
|
|
420
|
-
if ("superClass" in node && node.superClass) {
|
|
413
|
+
if ("superClass" in node && node.superClass != null) {
|
|
421
414
|
const re = /^PureComponent$/u;
|
|
422
415
|
switch (true) {
|
|
423
416
|
case node.superClass.type === types.AST_NODE_TYPES.Identifier:
|
|
@@ -440,13 +433,13 @@ function isFunctionOfRenderMethod(node) {
|
|
|
440
433
|
return isClassComponent(node.parent.parent.parent);
|
|
441
434
|
}
|
|
442
435
|
function isInsideRenderMethod(node) {
|
|
443
|
-
return
|
|
436
|
+
return AST8__namespace.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
|
|
444
437
|
}
|
|
445
438
|
|
|
446
439
|
// src/component/misc.ts
|
|
447
440
|
function hasNoneOrValidComponentName(node, context) {
|
|
448
441
|
const id2 = getFunctionComponentIdentifier(node, context);
|
|
449
|
-
if (
|
|
442
|
+
if (id2 == null) return true;
|
|
450
443
|
const name = Array.isArray(id2) ? id2.at(-1)?.name : id2.name;
|
|
451
444
|
return name != null && isComponentName(name);
|
|
452
445
|
}
|
|
@@ -478,19 +471,21 @@ function hasValidHierarchy(node, context, hint) {
|
|
|
478
471
|
types.AST_NODE_TYPES.ClassBody
|
|
479
472
|
])
|
|
480
473
|
);
|
|
481
|
-
return
|
|
474
|
+
return boundaryNode == null || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
|
|
482
475
|
}
|
|
483
476
|
function getComponentFlag(initPath) {
|
|
484
477
|
let flag = ERFunctionComponentFlag.None;
|
|
485
|
-
if (initPath && AST8__namespace.hasCallInFunctionInitPath("memo"
|
|
478
|
+
if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("memo", initPath)) {
|
|
486
479
|
flag |= ERFunctionComponentFlag.Memo;
|
|
487
480
|
}
|
|
488
|
-
if (initPath && AST8__namespace.hasCallInFunctionInitPath("forwardRef"
|
|
481
|
+
if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
489
482
|
flag |= ERFunctionComponentFlag.ForwardRef;
|
|
490
483
|
}
|
|
491
484
|
return flag;
|
|
492
485
|
}
|
|
493
|
-
|
|
486
|
+
var displayNameAssignmentSelector = "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']";
|
|
487
|
+
function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options = {}) {
|
|
488
|
+
const { collectDisplayName = false, collectHookCalls = false } = options;
|
|
494
489
|
const jsxCtx = { getScope: (node) => context.sourceCode.getScope(node) };
|
|
495
490
|
const components = /* @__PURE__ */ new Map();
|
|
496
491
|
const functionEntries = [];
|
|
@@ -501,12 +496,12 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
501
496
|
};
|
|
502
497
|
const onFunctionExit = () => {
|
|
503
498
|
const entry = functionEntries.at(-1);
|
|
504
|
-
if (
|
|
499
|
+
if (entry == null) return;
|
|
505
500
|
if (!entry.isComponent) {
|
|
506
501
|
return functionEntries.pop();
|
|
507
502
|
}
|
|
508
503
|
const shouldDrop = AST8__namespace.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
509
|
-
return context.sourceCode.getScope(r).block === entry.node &&
|
|
504
|
+
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX4__namespace.isJSXValue(r.argument, jsxCtx, hint);
|
|
510
505
|
});
|
|
511
506
|
if (shouldDrop) {
|
|
512
507
|
components.delete(entry.key);
|
|
@@ -528,7 +523,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
528
523
|
":function[type]:exit": onFunctionExit,
|
|
529
524
|
"ArrowFunctionExpression[type][body.type!='BlockStatement']"() {
|
|
530
525
|
const entry = getCurrentEntry();
|
|
531
|
-
if (
|
|
526
|
+
if (entry == null) {
|
|
532
527
|
return;
|
|
533
528
|
}
|
|
534
529
|
const { body } = entry.node;
|
|
@@ -538,11 +533,11 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
538
533
|
}
|
|
539
534
|
const initPath = AST8__namespace.getFunctionInitPath(entry.node);
|
|
540
535
|
const id2 = getFunctionComponentIdentifier(entry.node, context);
|
|
541
|
-
const name =
|
|
536
|
+
const name = getComponentNameFromIdentifier(id2);
|
|
542
537
|
const key = getId();
|
|
543
538
|
components.set(key, {
|
|
544
|
-
_: key,
|
|
545
539
|
id: id2,
|
|
540
|
+
key,
|
|
546
541
|
kind: "function",
|
|
547
542
|
name,
|
|
548
543
|
node: entry.node,
|
|
@@ -553,32 +548,32 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
553
548
|
initPath
|
|
554
549
|
});
|
|
555
550
|
},
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
displayName: right
|
|
566
|
-
});
|
|
567
|
-
},
|
|
568
|
-
"CallExpression[type]:exit"(node) {
|
|
569
|
-
if (!isReactHookCall(node)) {
|
|
570
|
-
return;
|
|
551
|
+
...collectDisplayName ? {
|
|
552
|
+
[displayNameAssignmentSelector](node) {
|
|
553
|
+
const { left, right } = node;
|
|
554
|
+
const componentName = left.object.type === types.AST_NODE_TYPES.Identifier ? left.object.name : eff._;
|
|
555
|
+
const component = [...components.values()].findLast(({ name }) => name != null && name === componentName);
|
|
556
|
+
if (component == null) {
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
component.displayName = right;
|
|
571
560
|
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
561
|
+
} : {},
|
|
562
|
+
...collectHookCalls ? {
|
|
563
|
+
"CallExpression[type]:exit"(node) {
|
|
564
|
+
if (!isReactHookCall(node)) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
const entry = getCurrentEntry();
|
|
568
|
+
if (entry == null) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
entry.hookCalls.push(node);
|
|
575
572
|
}
|
|
576
|
-
|
|
577
|
-
functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
|
|
578
|
-
},
|
|
573
|
+
} : {},
|
|
579
574
|
"ReturnStatement[type]"(node) {
|
|
580
575
|
const entry = getCurrentEntry();
|
|
581
|
-
if (
|
|
576
|
+
if (entry == null) {
|
|
582
577
|
return;
|
|
583
578
|
}
|
|
584
579
|
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4__namespace.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
@@ -589,10 +584,10 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
589
584
|
functionEntries.push({ ...entry, isComponent });
|
|
590
585
|
const initPath = AST8__namespace.getFunctionInitPath(entry.node);
|
|
591
586
|
const id2 = getFunctionComponentIdentifier(entry.node, context);
|
|
592
|
-
const name =
|
|
587
|
+
const name = getComponentNameFromIdentifier(id2);
|
|
593
588
|
components.set(entry.key, {
|
|
594
|
-
_: entry.key,
|
|
595
589
|
id: id2,
|
|
590
|
+
key: entry.key,
|
|
596
591
|
kind: "function",
|
|
597
592
|
name,
|
|
598
593
|
node: entry.node,
|
|
@@ -624,8 +619,8 @@ function useComponentCollectorLegacy() {
|
|
|
624
619
|
components.set(
|
|
625
620
|
key,
|
|
626
621
|
{
|
|
627
|
-
_: key,
|
|
628
622
|
id: id2,
|
|
623
|
+
key,
|
|
629
624
|
kind: "class",
|
|
630
625
|
name: id2?.name,
|
|
631
626
|
node,
|
|
@@ -645,13 +640,13 @@ function useComponentCollectorLegacy() {
|
|
|
645
640
|
return { ctx, listeners };
|
|
646
641
|
}
|
|
647
642
|
function isSetupFunction(node) {
|
|
648
|
-
if (node
|
|
643
|
+
if (node == null) return eff._;
|
|
649
644
|
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);
|
|
650
645
|
}
|
|
651
646
|
function isCleanupFunction(node) {
|
|
652
|
-
const nearReturn = AST8__namespace.
|
|
653
|
-
const nearFunction = AST8__namespace.
|
|
654
|
-
const nearFunctionOfReturn = AST8__namespace.
|
|
647
|
+
const nearReturn = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
|
|
648
|
+
const nearFunction = AST8__namespace.findParentNode(node, AST8__namespace.isFunction);
|
|
649
|
+
const nearFunctionOfReturn = AST8__namespace.findParentNode(nearReturn, AST8__namespace.isFunction);
|
|
655
650
|
return nearFunction === nearFunctionOfReturn && isSetupFunction(nearFunction);
|
|
656
651
|
}
|
|
657
652
|
function isComponentDidMount(node) {
|
|
@@ -675,13 +670,13 @@ function isDirectValueOfRenderPropertyLoose(node) {
|
|
|
675
670
|
const matching = (node2) => {
|
|
676
671
|
return node2.type === types.AST_NODE_TYPES.Property && node2.key.type === types.AST_NODE_TYPES.Identifier && node2.key.name.startsWith("render");
|
|
677
672
|
};
|
|
678
|
-
return matching(node) ||
|
|
673
|
+
return matching(node) || node.parent != null && matching(node.parent);
|
|
679
674
|
}
|
|
680
675
|
function isDeclaredInRenderPropLoose(node) {
|
|
681
676
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
682
677
|
return true;
|
|
683
678
|
}
|
|
684
|
-
const parent = AST8__namespace.
|
|
679
|
+
const parent = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
685
680
|
if (parent?.type !== types.AST_NODE_TYPES.JSXAttribute) {
|
|
686
681
|
return false;
|
|
687
682
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -10,7 +10,7 @@ function getElementNameAndRepresentName(node, context, polymorphicPropName, addi
|
|
|
10
10
|
const name = JSX4.getElementName(node);
|
|
11
11
|
if (name === name.toLowerCase()) return [name, name];
|
|
12
12
|
const component = additionalComponents.findLast((c) => c.name === name || c.re.test(name));
|
|
13
|
-
if (component
|
|
13
|
+
if (component != null) return [name, component.as];
|
|
14
14
|
if (polymorphicPropName == null) return [name, name];
|
|
15
15
|
const initialScope = context.sourceCode.getScope(node);
|
|
16
16
|
const polymorphicProp = JSX4.findPropInAttributes(
|
|
@@ -18,7 +18,7 @@ function getElementNameAndRepresentName(node, context, polymorphicPropName, addi
|
|
|
18
18
|
initialScope,
|
|
19
19
|
node.attributes
|
|
20
20
|
);
|
|
21
|
-
if (polymorphicProp
|
|
21
|
+
if (polymorphicProp == null) return [name, name];
|
|
22
22
|
const polymorphicName = VAR.toResolved(JSX4.getPropValue(polymorphicProp, initialScope)).value;
|
|
23
23
|
if (typeof polymorphicName === "string") {
|
|
24
24
|
return [name, polymorphicName];
|
|
@@ -140,15 +140,15 @@ var isMemoCall = isReactAPICallWithName("memo");
|
|
|
140
140
|
|
|
141
141
|
// src/element/hierarchy.ts
|
|
142
142
|
function isInsideCreateElementProps(node, context) {
|
|
143
|
-
const call = AST8.
|
|
144
|
-
if (
|
|
145
|
-
const prop = AST8.
|
|
146
|
-
if (
|
|
143
|
+
const call = AST8.findParentNode(node, isCreateElementCall(context));
|
|
144
|
+
if (call == null) return false;
|
|
145
|
+
const prop = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.ObjectExpression));
|
|
146
|
+
if (prop == null) return false;
|
|
147
147
|
return prop === call.arguments[1];
|
|
148
148
|
}
|
|
149
149
|
function isChildrenOfCreateElement(node, context) {
|
|
150
150
|
const parent = node.parent;
|
|
151
|
-
if (
|
|
151
|
+
if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
|
|
152
152
|
if (!isCreateElementCall(parent, context)) return false;
|
|
153
153
|
return parent.arguments.slice(2).some((arg) => arg === node);
|
|
154
154
|
}
|
|
@@ -161,12 +161,12 @@ function isReactHookName(name) {
|
|
|
161
161
|
|
|
162
162
|
// src/hook/is.ts
|
|
163
163
|
function isReactHook(node) {
|
|
164
|
-
if (node
|
|
164
|
+
if (node == null) return _;
|
|
165
165
|
const id2 = AST8.getFunctionIdentifier(node);
|
|
166
|
-
return id2?.name
|
|
166
|
+
return id2?.name != null && isReactHookName(id2.name);
|
|
167
167
|
}
|
|
168
168
|
function isReactHookCall(node) {
|
|
169
|
-
if (node
|
|
169
|
+
if (node == null) return false;
|
|
170
170
|
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
171
171
|
return false;
|
|
172
172
|
}
|
|
@@ -179,7 +179,7 @@ function isReactHookCall(node) {
|
|
|
179
179
|
return false;
|
|
180
180
|
}
|
|
181
181
|
function isReactHookCallWithName(node, context) {
|
|
182
|
-
if (node
|
|
182
|
+
if (node == null) return returnFalse;
|
|
183
183
|
const settings = unsafeDecodeSettings(context.settings);
|
|
184
184
|
return (name) => {
|
|
185
185
|
const initialScope = context.sourceCode.getScope(node);
|
|
@@ -194,7 +194,7 @@ function isReactHookCallWithName(node, context) {
|
|
|
194
194
|
};
|
|
195
195
|
}
|
|
196
196
|
function isReactHookCallWithNameLoose(node) {
|
|
197
|
-
if (node
|
|
197
|
+
if (node == null) return returnFalse;
|
|
198
198
|
return (name) => {
|
|
199
199
|
switch (node.callee.type) {
|
|
200
200
|
case AST_NODE_TYPES.Identifier:
|
|
@@ -221,7 +221,7 @@ function isReactHookCallWithNameAlias(name, context, alias) {
|
|
|
221
221
|
};
|
|
222
222
|
}
|
|
223
223
|
function isUseEffectCallLoose(node) {
|
|
224
|
-
if (node
|
|
224
|
+
if (node == null) return false;
|
|
225
225
|
if (node.type !== AST_NODE_TYPES.CallExpression) {
|
|
226
226
|
return false;
|
|
227
227
|
}
|
|
@@ -252,7 +252,7 @@ var isUseTransitionCall = flip(isReactHookCallWithName)("useTransition");
|
|
|
252
252
|
|
|
253
253
|
// src/hook/hierarchy.ts
|
|
254
254
|
function isInsideReactHook(node) {
|
|
255
|
-
return isReactHook(AST8.
|
|
255
|
+
return isReactHook(AST8.findParentNode(node, AST8.isFunction));
|
|
256
256
|
}
|
|
257
257
|
function useHookCollector() {
|
|
258
258
|
const hooks = /* @__PURE__ */ new Map();
|
|
@@ -260,12 +260,12 @@ function useHookCollector() {
|
|
|
260
260
|
const onFunctionEnter = (node) => {
|
|
261
261
|
const id2 = AST8.getFunctionIdentifier(node);
|
|
262
262
|
const name = id2?.name;
|
|
263
|
-
if (name
|
|
263
|
+
if (name != null && isReactHookName(name)) {
|
|
264
264
|
const key = getId();
|
|
265
265
|
fEntries.push({ key, node });
|
|
266
266
|
hooks.set(key, {
|
|
267
|
-
_: key,
|
|
268
267
|
id: id2,
|
|
268
|
+
key,
|
|
269
269
|
kind: "function",
|
|
270
270
|
name,
|
|
271
271
|
node,
|
|
@@ -297,20 +297,14 @@ function useHookCollector() {
|
|
|
297
297
|
return;
|
|
298
298
|
}
|
|
299
299
|
const fEntry = fEntries.at(-1);
|
|
300
|
-
if (fEntry?.key
|
|
300
|
+
if (fEntry?.key == null) {
|
|
301
301
|
return;
|
|
302
302
|
}
|
|
303
303
|
const hook = hooks.get(fEntry.key);
|
|
304
|
-
if (hook
|
|
304
|
+
if (hook == null) {
|
|
305
305
|
return;
|
|
306
306
|
}
|
|
307
|
-
|
|
308
|
-
...hook,
|
|
309
|
-
hookCalls: [
|
|
310
|
-
...hook.hookCalls,
|
|
311
|
-
node
|
|
312
|
-
]
|
|
313
|
-
});
|
|
307
|
+
hook.hookCalls.push(node);
|
|
314
308
|
}
|
|
315
309
|
};
|
|
316
310
|
return { ctx, listeners };
|
|
@@ -359,7 +353,7 @@ function isComponentWrapperCall(node, context) {
|
|
|
359
353
|
}
|
|
360
354
|
function getFunctionComponentIdentifier(node, context) {
|
|
361
355
|
const functionId = AST8.getFunctionIdentifier(node);
|
|
362
|
-
if (functionId) {
|
|
356
|
+
if (functionId != null) {
|
|
363
357
|
return functionId;
|
|
364
358
|
}
|
|
365
359
|
const { parent } = node;
|
|
@@ -371,17 +365,16 @@ function getFunctionComponentIdentifier(node, context) {
|
|
|
371
365
|
}
|
|
372
366
|
return _;
|
|
373
367
|
}
|
|
374
|
-
|
|
375
|
-
// src/component/component-name.ts
|
|
376
368
|
var RE_COMPONENT_NAME = /^_?[A-Z]/u;
|
|
377
369
|
function getComponentNameFromIdentifier(node) {
|
|
370
|
+
if (node == null) return _;
|
|
378
371
|
return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
|
|
379
372
|
}
|
|
380
373
|
function isComponentName(name) {
|
|
381
374
|
return RE_COMPONENT_NAME.test(name);
|
|
382
375
|
}
|
|
383
376
|
function isClassComponent(node) {
|
|
384
|
-
if ("superClass" in node && node.superClass) {
|
|
377
|
+
if ("superClass" in node && node.superClass != null) {
|
|
385
378
|
const re = /^(?:Pure)?Component$/u;
|
|
386
379
|
switch (true) {
|
|
387
380
|
case node.superClass.type === AST_NODE_TYPES.Identifier:
|
|
@@ -393,7 +386,7 @@ function isClassComponent(node) {
|
|
|
393
386
|
return false;
|
|
394
387
|
}
|
|
395
388
|
function isPureComponent(node) {
|
|
396
|
-
if ("superClass" in node && node.superClass) {
|
|
389
|
+
if ("superClass" in node && node.superClass != null) {
|
|
397
390
|
const re = /^PureComponent$/u;
|
|
398
391
|
switch (true) {
|
|
399
392
|
case node.superClass.type === AST_NODE_TYPES.Identifier:
|
|
@@ -416,13 +409,13 @@ function isFunctionOfRenderMethod(node) {
|
|
|
416
409
|
return isClassComponent(node.parent.parent.parent);
|
|
417
410
|
}
|
|
418
411
|
function isInsideRenderMethod(node) {
|
|
419
|
-
return
|
|
412
|
+
return AST8.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
|
|
420
413
|
}
|
|
421
414
|
|
|
422
415
|
// src/component/misc.ts
|
|
423
416
|
function hasNoneOrValidComponentName(node, context) {
|
|
424
417
|
const id2 = getFunctionComponentIdentifier(node, context);
|
|
425
|
-
if (
|
|
418
|
+
if (id2 == null) return true;
|
|
426
419
|
const name = Array.isArray(id2) ? id2.at(-1)?.name : id2.name;
|
|
427
420
|
return name != null && isComponentName(name);
|
|
428
421
|
}
|
|
@@ -454,19 +447,21 @@ function hasValidHierarchy(node, context, hint) {
|
|
|
454
447
|
AST_NODE_TYPES.ClassBody
|
|
455
448
|
])
|
|
456
449
|
);
|
|
457
|
-
return
|
|
450
|
+
return boundaryNode == null || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
|
|
458
451
|
}
|
|
459
452
|
function getComponentFlag(initPath) {
|
|
460
453
|
let flag = ERFunctionComponentFlag.None;
|
|
461
|
-
if (initPath && AST8.hasCallInFunctionInitPath("memo"
|
|
454
|
+
if (initPath != null && AST8.hasCallInFunctionInitPath("memo", initPath)) {
|
|
462
455
|
flag |= ERFunctionComponentFlag.Memo;
|
|
463
456
|
}
|
|
464
|
-
if (initPath && AST8.hasCallInFunctionInitPath("forwardRef"
|
|
457
|
+
if (initPath != null && AST8.hasCallInFunctionInitPath("forwardRef", initPath)) {
|
|
465
458
|
flag |= ERFunctionComponentFlag.ForwardRef;
|
|
466
459
|
}
|
|
467
460
|
return flag;
|
|
468
461
|
}
|
|
469
|
-
|
|
462
|
+
var displayNameAssignmentSelector = "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']";
|
|
463
|
+
function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options = {}) {
|
|
464
|
+
const { collectDisplayName = false, collectHookCalls = false } = options;
|
|
470
465
|
const jsxCtx = { getScope: (node) => context.sourceCode.getScope(node) };
|
|
471
466
|
const components = /* @__PURE__ */ new Map();
|
|
472
467
|
const functionEntries = [];
|
|
@@ -477,12 +472,12 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
477
472
|
};
|
|
478
473
|
const onFunctionExit = () => {
|
|
479
474
|
const entry = functionEntries.at(-1);
|
|
480
|
-
if (
|
|
475
|
+
if (entry == null) return;
|
|
481
476
|
if (!entry.isComponent) {
|
|
482
477
|
return functionEntries.pop();
|
|
483
478
|
}
|
|
484
479
|
const shouldDrop = AST8.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
|
|
485
|
-
return context.sourceCode.getScope(r).block === entry.node &&
|
|
480
|
+
return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX4.isJSXValue(r.argument, jsxCtx, hint);
|
|
486
481
|
});
|
|
487
482
|
if (shouldDrop) {
|
|
488
483
|
components.delete(entry.key);
|
|
@@ -504,7 +499,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
504
499
|
":function[type]:exit": onFunctionExit,
|
|
505
500
|
"ArrowFunctionExpression[type][body.type!='BlockStatement']"() {
|
|
506
501
|
const entry = getCurrentEntry();
|
|
507
|
-
if (
|
|
502
|
+
if (entry == null) {
|
|
508
503
|
return;
|
|
509
504
|
}
|
|
510
505
|
const { body } = entry.node;
|
|
@@ -514,11 +509,11 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
514
509
|
}
|
|
515
510
|
const initPath = AST8.getFunctionInitPath(entry.node);
|
|
516
511
|
const id2 = getFunctionComponentIdentifier(entry.node, context);
|
|
517
|
-
const name =
|
|
512
|
+
const name = getComponentNameFromIdentifier(id2);
|
|
518
513
|
const key = getId();
|
|
519
514
|
components.set(key, {
|
|
520
|
-
_: key,
|
|
521
515
|
id: id2,
|
|
516
|
+
key,
|
|
522
517
|
kind: "function",
|
|
523
518
|
name,
|
|
524
519
|
node: entry.node,
|
|
@@ -529,32 +524,32 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
529
524
|
initPath
|
|
530
525
|
});
|
|
531
526
|
},
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
displayName: right
|
|
542
|
-
});
|
|
543
|
-
},
|
|
544
|
-
"CallExpression[type]:exit"(node) {
|
|
545
|
-
if (!isReactHookCall(node)) {
|
|
546
|
-
return;
|
|
527
|
+
...collectDisplayName ? {
|
|
528
|
+
[displayNameAssignmentSelector](node) {
|
|
529
|
+
const { left, right } = node;
|
|
530
|
+
const componentName = left.object.type === AST_NODE_TYPES.Identifier ? left.object.name : _;
|
|
531
|
+
const component = [...components.values()].findLast(({ name }) => name != null && name === componentName);
|
|
532
|
+
if (component == null) {
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
component.displayName = right;
|
|
547
536
|
}
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
537
|
+
} : {},
|
|
538
|
+
...collectHookCalls ? {
|
|
539
|
+
"CallExpression[type]:exit"(node) {
|
|
540
|
+
if (!isReactHookCall(node)) {
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
const entry = getCurrentEntry();
|
|
544
|
+
if (entry == null) {
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
entry.hookCalls.push(node);
|
|
551
548
|
}
|
|
552
|
-
|
|
553
|
-
functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
|
|
554
|
-
},
|
|
549
|
+
} : {},
|
|
555
550
|
"ReturnStatement[type]"(node) {
|
|
556
551
|
const entry = getCurrentEntry();
|
|
557
|
-
if (
|
|
552
|
+
if (entry == null) {
|
|
558
553
|
return;
|
|
559
554
|
}
|
|
560
555
|
const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
|
|
@@ -565,10 +560,10 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
|
|
|
565
560
|
functionEntries.push({ ...entry, isComponent });
|
|
566
561
|
const initPath = AST8.getFunctionInitPath(entry.node);
|
|
567
562
|
const id2 = getFunctionComponentIdentifier(entry.node, context);
|
|
568
|
-
const name =
|
|
563
|
+
const name = getComponentNameFromIdentifier(id2);
|
|
569
564
|
components.set(entry.key, {
|
|
570
|
-
_: entry.key,
|
|
571
565
|
id: id2,
|
|
566
|
+
key: entry.key,
|
|
572
567
|
kind: "function",
|
|
573
568
|
name,
|
|
574
569
|
node: entry.node,
|
|
@@ -600,8 +595,8 @@ function useComponentCollectorLegacy() {
|
|
|
600
595
|
components.set(
|
|
601
596
|
key,
|
|
602
597
|
{
|
|
603
|
-
_: key,
|
|
604
598
|
id: id2,
|
|
599
|
+
key,
|
|
605
600
|
kind: "class",
|
|
606
601
|
name: id2?.name,
|
|
607
602
|
node,
|
|
@@ -621,13 +616,13 @@ function useComponentCollectorLegacy() {
|
|
|
621
616
|
return { ctx, listeners };
|
|
622
617
|
}
|
|
623
618
|
function isSetupFunction(node) {
|
|
624
|
-
if (node
|
|
619
|
+
if (node == null) return _;
|
|
625
620
|
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);
|
|
626
621
|
}
|
|
627
622
|
function isCleanupFunction(node) {
|
|
628
|
-
const nearReturn = AST8.
|
|
629
|
-
const nearFunction = AST8.
|
|
630
|
-
const nearFunctionOfReturn = AST8.
|
|
623
|
+
const nearReturn = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.ReturnStatement));
|
|
624
|
+
const nearFunction = AST8.findParentNode(node, AST8.isFunction);
|
|
625
|
+
const nearFunctionOfReturn = AST8.findParentNode(nearReturn, AST8.isFunction);
|
|
631
626
|
return nearFunction === nearFunctionOfReturn && isSetupFunction(nearFunction);
|
|
632
627
|
}
|
|
633
628
|
function isComponentDidMount(node) {
|
|
@@ -651,13 +646,13 @@ function isDirectValueOfRenderPropertyLoose(node) {
|
|
|
651
646
|
const matching = (node2) => {
|
|
652
647
|
return node2.type === AST_NODE_TYPES.Property && node2.key.type === AST_NODE_TYPES.Identifier && node2.key.name.startsWith("render");
|
|
653
648
|
};
|
|
654
|
-
return matching(node) ||
|
|
649
|
+
return matching(node) || node.parent != null && matching(node.parent);
|
|
655
650
|
}
|
|
656
651
|
function isDeclaredInRenderPropLoose(node) {
|
|
657
652
|
if (isDirectValueOfRenderPropertyLoose(node)) {
|
|
658
653
|
return true;
|
|
659
654
|
}
|
|
660
|
-
const parent = AST8.
|
|
655
|
+
const parent = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
|
|
661
656
|
if (parent?.type !== AST_NODE_TYPES.JSXAttribute) {
|
|
662
657
|
return false;
|
|
663
658
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "1.24.0-beta.
|
|
3
|
+
"version": "1.24.0-beta.3",
|
|
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": {
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"@typescript-eslint/types": "^8.19.1",
|
|
39
39
|
"@typescript-eslint/utils": "^8.19.1",
|
|
40
40
|
"ts-pattern": "^5.6.0",
|
|
41
|
-
"@eslint-react/
|
|
42
|
-
"@eslint-react/
|
|
43
|
-
"@eslint-react/
|
|
44
|
-
"@eslint-react/
|
|
45
|
-
"@eslint-react/
|
|
46
|
-
"@eslint-react/
|
|
41
|
+
"@eslint-react/eff": "1.24.0-beta.3",
|
|
42
|
+
"@eslint-react/jsx": "1.24.0-beta.3",
|
|
43
|
+
"@eslint-react/shared": "1.24.0-beta.3",
|
|
44
|
+
"@eslint-react/types": "1.24.0-beta.3",
|
|
45
|
+
"@eslint-react/var": "1.24.0-beta.3",
|
|
46
|
+
"@eslint-react/ast": "1.24.0-beta.3"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"tsup": "^8.3.5",
|