@eslint-react/core 1.28.0-next.1 → 1.28.0-next.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 CHANGED
@@ -237,6 +237,9 @@ declare function isDeclaredInRenderPropLoose(node: TSESTree.Node): boolean;
237
237
  type ERStateKind = "actionState" | "state";
238
238
  declare function isThisSetState(node: TSESTree.CallExpression): boolean;
239
239
 
240
+ /** internal */
241
+ declare function hasValidHierarchy(node: AST.TSESTreeFunction, context: RuleContext, hint: bigint): boolean;
242
+
240
243
  /**
241
244
  * Check if a node is a React class component
242
245
  * @param node The AST node to check
@@ -326,30 +329,6 @@ interface ERSemanticEntry {
326
329
  phase: ERPhaseKind;
327
330
  }
328
331
 
329
- /**
330
- * The ESQuery selector for a component display name assignment expression
331
- */
332
- declare const DISPLAY_NAME_ASSIGNMENT_SELECTOR: string;
333
- /**
334
- * Check if the node is a component display name assignment expression
335
- * @param node The AST node
336
- * @returns `true` if the node is a component display name assignment
337
- */
338
- declare function isDisplayNameAssignment(node: TSESTree.Node | _): node is TSESTree.AssignmentExpression;
339
-
340
- /**
341
- * Checks if the given node is a call expression to the given function or method of the pragma
342
- * @param name The name of the function or method to check
343
- * @returns A predicate that checks if the given node is a call expression to the given function or method
344
- */
345
- declare function isFromReact(name: string): (node: TSESTree.Identifier | TSESTree.MemberExpression, context: RuleContext) => boolean;
346
- /**
347
- * @internal
348
- * @param memberName The name of the member object
349
- * @param name The name of the member property
350
- * @returns A function that checks if a given node is a member expression of a Pragma member.
351
- */
352
- declare function isFromReactMember(memberName: string, name: string): (node: TSESTree.MemberExpression, context: RuleContext) => boolean;
353
332
  declare namespace isCallFromReact {
354
333
  type ReturnType = {
355
334
  (context: RuleContext): (node: TSESTree.Node) => node is TSESTree.CallExpression;
@@ -369,6 +348,24 @@ declare namespace isCallFromReactMember {
369
348
  }
370
349
  declare function isCallFromReactMember(pragmaMemberName: string, name: string): isCallFromReactMember.ReturnType;
371
350
 
351
+ /**
352
+ * The ESQuery selector for a component display name assignment expression
353
+ */
354
+ declare const DISPLAY_NAME_ASSIGNMENT_SELECTOR: string;
355
+ /**
356
+ * Check if the node is a component display name assignment expression
357
+ * @param node The AST node
358
+ * @returns `true` if the node is a component display name assignment
359
+ */
360
+ declare function isDisplayNameAssignment(node: TSESTree.Node | _): node is TSESTree.AssignmentExpression;
361
+
362
+ declare function isFromReactLoose(node: TSESTree.Identifier | TSESTree.MemberExpression, name: string): boolean;
363
+ declare function isFromReactStrict(node: TSESTree.Identifier | TSESTree.MemberExpression, name: string, importSource: string, initialScope: Scope): boolean;
364
+ declare function isFromReact(name: string): (node: TSESTree.Identifier | TSESTree.MemberExpression, context: RuleContext) => boolean;
365
+ declare function isFromReactMemberLoose(node: TSESTree.MemberExpression, memberName: string, name: string): boolean;
366
+ declare function isFromReactMemberStrict(node: TSESTree.MemberExpression, memberName: string, name: string, importSource: string, initialScope: Scope): boolean;
367
+ declare function isFromReactMember(memberName: string, name: string): (node: TSESTree.MemberExpression, context: RuleContext) => boolean;
368
+
372
369
  /**
373
370
  * Check if an identifier is initialized from react
374
371
  * @param name The top-level identifier's name
@@ -2424,4 +2421,4 @@ declare const isCreateRefCall: isCallFromReact.ReturnType;
2424
2421
  declare const isForwardRefCall: isCallFromReact.ReturnType;
2425
2422
  declare const isMemoCall: isCallFromReact.ReturnType;
2426
2423
 
2427
- export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type ERClassComponent, type ERComponent, ERComponentFlag, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectPhaseKind, type ERFunctionComponent, type ERHook, type ERHookKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isDisplayNameAssignment, isForwardRef, isForwardRefCall, isFromReact, isFromReactMember, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
2424
+ export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type ERClassComponent, type ERComponent, ERComponentFlag, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectPhaseKind, type ERFunctionComponent, type ERHook, type ERHookKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isDisplayNameAssignment, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactMember, isFromReactMemberLoose, isFromReactMemberStrict, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
package/dist/index.d.ts CHANGED
@@ -237,6 +237,9 @@ declare function isDeclaredInRenderPropLoose(node: TSESTree.Node): boolean;
237
237
  type ERStateKind = "actionState" | "state";
238
238
  declare function isThisSetState(node: TSESTree.CallExpression): boolean;
239
239
 
240
+ /** internal */
241
+ declare function hasValidHierarchy(node: AST.TSESTreeFunction, context: RuleContext, hint: bigint): boolean;
242
+
240
243
  /**
241
244
  * Check if a node is a React class component
242
245
  * @param node The AST node to check
@@ -326,30 +329,6 @@ interface ERSemanticEntry {
326
329
  phase: ERPhaseKind;
327
330
  }
328
331
 
329
- /**
330
- * The ESQuery selector for a component display name assignment expression
331
- */
332
- declare const DISPLAY_NAME_ASSIGNMENT_SELECTOR: string;
333
- /**
334
- * Check if the node is a component display name assignment expression
335
- * @param node The AST node
336
- * @returns `true` if the node is a component display name assignment
337
- */
338
- declare function isDisplayNameAssignment(node: TSESTree.Node | _): node is TSESTree.AssignmentExpression;
339
-
340
- /**
341
- * Checks if the given node is a call expression to the given function or method of the pragma
342
- * @param name The name of the function or method to check
343
- * @returns A predicate that checks if the given node is a call expression to the given function or method
344
- */
345
- declare function isFromReact(name: string): (node: TSESTree.Identifier | TSESTree.MemberExpression, context: RuleContext) => boolean;
346
- /**
347
- * @internal
348
- * @param memberName The name of the member object
349
- * @param name The name of the member property
350
- * @returns A function that checks if a given node is a member expression of a Pragma member.
351
- */
352
- declare function isFromReactMember(memberName: string, name: string): (node: TSESTree.MemberExpression, context: RuleContext) => boolean;
353
332
  declare namespace isCallFromReact {
354
333
  type ReturnType = {
355
334
  (context: RuleContext): (node: TSESTree.Node) => node is TSESTree.CallExpression;
@@ -369,6 +348,24 @@ declare namespace isCallFromReactMember {
369
348
  }
370
349
  declare function isCallFromReactMember(pragmaMemberName: string, name: string): isCallFromReactMember.ReturnType;
371
350
 
351
+ /**
352
+ * The ESQuery selector for a component display name assignment expression
353
+ */
354
+ declare const DISPLAY_NAME_ASSIGNMENT_SELECTOR: string;
355
+ /**
356
+ * Check if the node is a component display name assignment expression
357
+ * @param node The AST node
358
+ * @returns `true` if the node is a component display name assignment
359
+ */
360
+ declare function isDisplayNameAssignment(node: TSESTree.Node | _): node is TSESTree.AssignmentExpression;
361
+
362
+ declare function isFromReactLoose(node: TSESTree.Identifier | TSESTree.MemberExpression, name: string): boolean;
363
+ declare function isFromReactStrict(node: TSESTree.Identifier | TSESTree.MemberExpression, name: string, importSource: string, initialScope: Scope): boolean;
364
+ declare function isFromReact(name: string): (node: TSESTree.Identifier | TSESTree.MemberExpression, context: RuleContext) => boolean;
365
+ declare function isFromReactMemberLoose(node: TSESTree.MemberExpression, memberName: string, name: string): boolean;
366
+ declare function isFromReactMemberStrict(node: TSESTree.MemberExpression, memberName: string, name: string, importSource: string, initialScope: Scope): boolean;
367
+ declare function isFromReactMember(memberName: string, name: string): (node: TSESTree.MemberExpression, context: RuleContext) => boolean;
368
+
372
369
  /**
373
370
  * Check if an identifier is initialized from react
374
371
  * @param name The top-level identifier's name
@@ -2424,4 +2421,4 @@ declare const isCreateRefCall: isCallFromReact.ReturnType;
2424
2421
  declare const isForwardRefCall: isCallFromReact.ReturnType;
2425
2422
  declare const isMemoCall: isCallFromReact.ReturnType;
2426
2423
 
2427
- export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type ERClassComponent, type ERComponent, ERComponentFlag, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectPhaseKind, type ERFunctionComponent, type ERHook, type ERHookKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isDisplayNameAssignment, isForwardRef, isForwardRefCall, isFromReact, isFromReactMember, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
2424
+ export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, type ERClassComponent, type ERComponent, ERComponentFlag, ERComponentHint, type ERComponentKind, type EREffectKind, type EREffectPhaseKind, type ERFunctionComponent, type ERHook, type ERHookKind, type ERLifecyclePhaseKind, type ERPhaseKind, ERPhaseRelevance, type ERSemanticEntry, type ERSemanticNode, type ERStateKind, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isDisplayNameAssignment, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactMember, isFromReactMemberLoose, isFromReactMemberStrict, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var AST9 = require('@eslint-react/ast');
3
+ var AST8 = require('@eslint-react/ast');
4
4
  var eff = require('@eslint-react/eff');
5
5
  var JSX3 = require('@eslint-react/jsx');
6
6
  var shared = require('@eslint-react/shared');
@@ -29,23 +29,12 @@ function _interopNamespace(e) {
29
29
  return Object.freeze(n);
30
30
  }
31
31
 
32
- var AST9__namespace = /*#__PURE__*/_interopNamespace(AST9);
32
+ var AST8__namespace = /*#__PURE__*/_interopNamespace(AST8);
33
33
  var JSX3__namespace = /*#__PURE__*/_interopNamespace(JSX3);
34
34
  var VAR__namespace = /*#__PURE__*/_interopNamespace(VAR);
35
35
  var birecord__default = /*#__PURE__*/_interopDefault(birecord);
36
36
 
37
37
  // src/component/component-collector.ts
38
- var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
39
- "AssignmentExpression",
40
- "[type]",
41
- "[operator='=']",
42
- "[left.type='MemberExpression']",
43
- "[left.property.name='displayName']"
44
- ].join("");
45
- function isDisplayNameAssignment(node) {
46
- if (node == null) return false;
47
- return node.type === types.AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === types.AST_NODE_TYPES.MemberExpression && node.left.property.type === types.AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
48
- }
49
38
  function getRequireExpressionArguments(node) {
50
39
  return tsPattern.match(node).with({ type: types.AST_NODE_TYPES.CallExpression, arguments: tsPattern.P.select(), callee: { type: types.AST_NODE_TYPES.Identifier, name: "require" } }, eff.identity).with({ type: types.AST_NODE_TYPES.MemberExpression, object: tsPattern.P.select() }, getRequireExpressionArguments).otherwise(() => eff._);
51
40
  }
@@ -64,7 +53,7 @@ function isInitializedFromReact(name, source, initialScope) {
64
53
  }
65
54
  const args = getRequireExpressionArguments(init);
66
55
  const arg0 = args?.[0];
67
- if (arg0 == null || !AST9__namespace.isStringLiteral(arg0)) {
56
+ if (arg0 == null || !AST8__namespace.isKindOfLiteral(arg0, "string")) {
68
57
  return false;
69
58
  }
70
59
  return arg0.value === source || arg0.value.startsWith(`${source}/`);
@@ -73,65 +62,85 @@ function isInitializedFromReact(name, source, initialScope) {
73
62
  }
74
63
 
75
64
  // src/utils/is-from-react.ts
65
+ var defaultImportSource = shared.DEFAULT_ESLINT_REACT_SETTINGS.importSource;
66
+ function isFromReactLoose(node, name) {
67
+ if (node.type === types.AST_NODE_TYPES.MemberExpression) {
68
+ return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name;
69
+ }
70
+ return node.name === name;
71
+ }
72
+ function isFromReactStrict(node, name, importSource, initialScope) {
73
+ if (node.type === types.AST_NODE_TYPES.MemberExpression) {
74
+ return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name && isInitializedFromReact(node.object.name, importSource, initialScope);
75
+ }
76
+ if (node.name === name) {
77
+ return isInitializedFromReact(name, importSource, initialScope);
78
+ }
79
+ return false;
80
+ }
76
81
  function isFromReact(name) {
77
82
  return (node, context) => {
78
- const settings = shared.unsafeDecodeSettings(context.settings);
79
- if (!settings.strictImportCheck) {
80
- if (node.type === types.AST_NODE_TYPES.MemberExpression) {
81
- return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name;
82
- }
83
- return node.name === name;
84
- }
85
- const importSource = settings.importSource ?? shared.DEFAULT_ESLINT_REACT_SETTINGS.importSource;
86
- const initialScope = context.sourceCode.getScope(node);
87
- if (node.type === types.AST_NODE_TYPES.MemberExpression) {
88
- return node.object.type === types.AST_NODE_TYPES.Identifier && node.property.type === types.AST_NODE_TYPES.Identifier && node.property.name === name && isInitializedFromReact(node.object.name, importSource, initialScope);
89
- }
90
- if (node.name === name) {
91
- return isInitializedFromReact(name, importSource, initialScope);
92
- }
93
- return false;
83
+ const { importSource = defaultImportSource, strictImportCheck = false } = shared.unsafeDecodeSettings(context.settings);
84
+ if (!strictImportCheck) return isFromReactLoose(node, name);
85
+ return isFromReactStrict(node, name, importSource, context.sourceCode.getScope(node));
94
86
  };
95
87
  }
88
+ function isFromReactMemberLoose(node, memberName, name) {
89
+ const { object, property } = node;
90
+ if (property.type !== types.AST_NODE_TYPES.Identifier || property.name !== name) return false;
91
+ if (object.type === types.AST_NODE_TYPES.Identifier && object.name === memberName) return true;
92
+ if (object.type === types.AST_NODE_TYPES.MemberExpression && object.object.type === types.AST_NODE_TYPES.Identifier && object.property.type === types.AST_NODE_TYPES.Identifier) {
93
+ return object.property.name === memberName;
94
+ }
95
+ return false;
96
+ }
97
+ function isFromReactMemberStrict(node, memberName, name, importSource, initialScope) {
98
+ const { object, property } = node;
99
+ if (property.type !== types.AST_NODE_TYPES.Identifier || property.name !== name) {
100
+ return false;
101
+ }
102
+ if (object.type === types.AST_NODE_TYPES.Identifier && object.name === memberName) {
103
+ return isInitializedFromReact(object.name, importSource, initialScope);
104
+ }
105
+ if (object.type === types.AST_NODE_TYPES.MemberExpression && object.object.type === types.AST_NODE_TYPES.Identifier && isInitializedFromReact(object.object.name, importSource, initialScope) && object.property.type === types.AST_NODE_TYPES.Identifier) {
106
+ return object.property.name === memberName;
107
+ }
108
+ return false;
109
+ }
96
110
  function isFromReactMember(memberName, name) {
97
111
  return (node, context) => {
98
- const settings = shared.unsafeDecodeSettings(context.settings);
99
- if (!settings.strictImportCheck) {
100
- if (node.property.type !== types.AST_NODE_TYPES.Identifier || node.property.name !== name) return false;
101
- if (node.object.type === types.AST_NODE_TYPES.Identifier && node.object.name === memberName) return true;
102
- if (node.object.type === types.AST_NODE_TYPES.MemberExpression && node.object.object.type === types.AST_NODE_TYPES.Identifier && node.object.property.type === types.AST_NODE_TYPES.Identifier) {
103
- return node.object.property.name === memberName;
104
- }
105
- return false;
106
- }
107
- const importSource = settings.importSource ?? shared.DEFAULT_ESLINT_REACT_SETTINGS.importSource;
108
- const initialScope = context.sourceCode.getScope(node);
109
- if (node.property.type !== types.AST_NODE_TYPES.Identifier || node.property.name !== name) {
110
- return false;
111
- }
112
- if (node.object.type === types.AST_NODE_TYPES.Identifier && node.object.name === memberName) {
113
- return isInitializedFromReact(node.object.name, importSource, initialScope);
114
- }
115
- if (node.object.type === types.AST_NODE_TYPES.MemberExpression && node.object.object.type === types.AST_NODE_TYPES.Identifier && isInitializedFromReact(node.object.object.name, importSource, initialScope) && node.object.property.type === types.AST_NODE_TYPES.Identifier) {
116
- return node.object.property.name === memberName;
117
- }
118
- return false;
112
+ const { importSource = defaultImportSource, strictImportCheck = false } = shared.unsafeDecodeSettings(context.settings);
113
+ if (!strictImportCheck) return isFromReactMemberLoose(node, memberName, name);
114
+ return isFromReactMemberStrict(node, memberName, name, importSource, context.sourceCode.getScope(node));
119
115
  };
120
116
  }
117
+
118
+ // src/utils/is-call-from-react.ts
121
119
  function isCallFromReact(name) {
122
120
  return eff.dual(2, (node, context) => {
123
121
  if (node.type !== types.AST_NODE_TYPES.CallExpression) return false;
124
- if (!AST9__namespace.isOneOf([types.AST_NODE_TYPES.Identifier, types.AST_NODE_TYPES.MemberExpression])(node.callee)) return false;
122
+ if (!AST8__namespace.isOneOf([types.AST_NODE_TYPES.Identifier, types.AST_NODE_TYPES.MemberExpression])(node.callee)) return false;
125
123
  return isFromReact(name)(node.callee, context);
126
124
  });
127
125
  }
128
126
  function isCallFromReactMember(pragmaMemberName, name) {
129
127
  return eff.dual(2, (node, context) => {
130
128
  if (node.type !== types.AST_NODE_TYPES.CallExpression) return false;
131
- if (!AST9__namespace.is(types.AST_NODE_TYPES.MemberExpression)(node.callee)) return false;
129
+ if (!AST8__namespace.is(types.AST_NODE_TYPES.MemberExpression)(node.callee)) return false;
132
130
  return isFromReactMember(pragmaMemberName, name)(node.callee, context);
133
131
  });
134
132
  }
133
+ var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
134
+ "AssignmentExpression",
135
+ "[type]",
136
+ "[operator='=']",
137
+ "[left.type='MemberExpression']",
138
+ "[left.property.name='displayName']"
139
+ ].join("");
140
+ function isDisplayNameAssignment(node) {
141
+ if (node == null) return false;
142
+ return node.type === types.AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === types.AST_NODE_TYPES.MemberExpression && node.left.property.type === types.AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
143
+ }
135
144
 
136
145
  // src/utils/is-react-api.ts
137
146
  function isReactAPIWithName(name, member) {
@@ -163,21 +172,6 @@ var isCreateRefCall = isReactAPICallWithName("createRef");
163
172
  var isForwardRefCall = isReactAPICallWithName("forwardRef");
164
173
  var isMemoCall = isReactAPICallWithName("memo");
165
174
 
166
- // src/element/hierarchy.ts
167
- function isInsideCreateElementProps(node, context) {
168
- const call = AST9__namespace.findParentNode(node, isCreateElementCall(context));
169
- if (call == null) return false;
170
- const prop = AST9__namespace.findParentNode(node, AST9__namespace.is(types.AST_NODE_TYPES.ObjectExpression));
171
- if (prop == null) return false;
172
- return prop === call.arguments[1];
173
- }
174
- function isChildrenOfCreateElement(node, context) {
175
- const parent = node.parent;
176
- if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
177
- if (!isCreateElementCall(parent, context)) return false;
178
- return parent.arguments.slice(2).some((arg) => arg === node);
179
- }
180
-
181
175
  // src/hook/hook-name.ts
182
176
  var RE_HOOK_NAME = /^use[A-Z\d]/u;
183
177
  function isReactHookName(name) {
@@ -187,7 +181,7 @@ function isReactHookName(name) {
187
181
  // src/hook/is.ts
188
182
  function isReactHook(node) {
189
183
  if (node == null) return eff._;
190
- const id = AST9__namespace.getFunctionIdentifier(node);
184
+ const id = AST8__namespace.getFunctionIdentifier(node);
191
185
  return id?.name != null && isReactHookName(id.name);
192
186
  }
193
187
  function isReactHookCall(node) {
@@ -279,13 +273,13 @@ var isUseTransitionCall = eff.flip(isReactHookCallWithName)("useTransition");
279
273
 
280
274
  // src/hook/hierarchy.ts
281
275
  function isInsideReactHook(node) {
282
- return isReactHook(AST9__namespace.findParentNode(node, AST9__namespace.isFunction));
276
+ return isReactHook(AST8__namespace.findParentNode(node, AST8__namespace.isFunction));
283
277
  }
284
278
  function useHookCollector() {
285
279
  const hooks = /* @__PURE__ */ new Map();
286
280
  const functionEntries = [];
287
281
  const onFunctionEnter = (node) => {
288
- const id = AST9__namespace.getFunctionIdentifier(node);
282
+ const id = AST8__namespace.getFunctionIdentifier(node);
289
283
  const key = shared.getId();
290
284
  const name = id?.name;
291
285
  if (name != null && isReactHookName(name)) {
@@ -381,7 +375,7 @@ function isComponentWrapperCall(node, context) {
381
375
  return isMemoCall(node, context) || isForwardRefCall(node, context) || isReactHookCallWithNameLoose(node)("useCallback");
382
376
  }
383
377
  function getFunctionComponentIdentifier(node, context) {
384
- const functionId = AST9__namespace.getFunctionIdentifier(node);
378
+ const functionId = AST8__namespace.getFunctionIdentifier(node);
385
379
  if (functionId != null) {
386
380
  return functionId;
387
381
  }
@@ -394,6 +388,33 @@ function getFunctionComponentIdentifier(node, context) {
394
388
  }
395
389
  return eff._;
396
390
  }
391
+ var RE_COMPONENT_NAME = /^_?[A-Z]/u;
392
+ function getComponentNameFromIdentifier(node) {
393
+ if (node == null) return eff._;
394
+ return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
395
+ }
396
+ function isComponentName(name) {
397
+ return RE_COMPONENT_NAME.test(name);
398
+ }
399
+ function hasNoneOrValidComponentName(node, context) {
400
+ const id = getFunctionComponentIdentifier(node, context);
401
+ if (id == null) return true;
402
+ const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
403
+ return name != null && isComponentName(name);
404
+ }
405
+ function isInsideCreateElementProps(node, context) {
406
+ const call = AST8__namespace.findParentNode(node, isCreateElementCall(context));
407
+ if (call == null) return false;
408
+ const prop = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.ObjectExpression));
409
+ if (prop == null) return false;
410
+ return prop === call.arguments[1];
411
+ }
412
+ function isChildrenOfCreateElement(node, context) {
413
+ const parent = node.parent;
414
+ if (parent == null || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
415
+ if (!isCreateElementCall(parent, context)) return false;
416
+ return parent.arguments.slice(2).some((arg) => arg === node);
417
+ }
397
418
  function isClassComponent(node) {
398
419
  if ("superClass" in node && node.superClass != null) {
399
420
  const re = /^(?:Pure)?Component$/u;
@@ -421,28 +442,28 @@ function isPureComponent(node) {
421
442
 
422
443
  // src/component/component-lifecycle.ts
423
444
  function isComponentDidMount(node) {
424
- return AST9__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
445
+ return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
425
446
  }
426
447
  function isComponentWillUnmount(node) {
427
- return AST9__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
448
+ return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
428
449
  }
429
450
  function isComponentDidCatch(node) {
430
- return AST9__namespace.isMethodOrProperty(node) && !node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
451
+ return AST8__namespace.isMethodOrProperty(node) && !node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
431
452
  }
432
453
  function isGetDerivedStateFromError(node) {
433
- return AST9__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
454
+ return AST8__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
434
455
  }
435
456
  function isGetDerivedStateFromProps(node) {
436
- return AST9__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
457
+ return AST8__namespace.isMethodOrProperty(node) && node.static && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
437
458
  }
438
459
  function isFunctionOfComponentDidMount(node) {
439
- return AST9__namespace.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
460
+ return AST8__namespace.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
440
461
  }
441
462
  function isFunctionOfComponentWillUnmount(node) {
442
- return AST9__namespace.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
463
+ return AST8__namespace.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
443
464
  }
444
465
  function isRenderMethodLike(node) {
445
- return AST9__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration;
466
+ return AST8__namespace.isMethodOrProperty(node) && node.key.type === types.AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === types.AST_NODE_TYPES.ClassDeclaration;
446
467
  }
447
468
  function isFunctionOfRenderMethod(node) {
448
469
  if (!isRenderMethodLike(node.parent)) {
@@ -451,21 +472,46 @@ function isFunctionOfRenderMethod(node) {
451
472
  return isClassComponent(node.parent.parent.parent);
452
473
  }
453
474
  function isInsideRenderMethod(node) {
454
- return AST9__namespace.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
475
+ return AST8__namespace.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
455
476
  }
456
- var RE_COMPONENT_NAME = /^_?[A-Z]/u;
457
- function getComponentNameFromIdentifier(node) {
458
- if (node == null) return eff._;
459
- return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
477
+
478
+ // src/component/hierarchy.ts
479
+ function hasValidHierarchy(node, context, hint) {
480
+ if (isChildrenOfCreateElement(node, context) || isFunctionOfRenderMethod(node)) {
481
+ return false;
482
+ }
483
+ if (hint & ERComponentHint.SkipMapCallback && AST8__namespace.isMapCallLoose(node.parent)) {
484
+ return false;
485
+ }
486
+ if (hint & ERComponentHint.SkipObjectMethod && isFunctionOfObjectMethod(node.parent)) {
487
+ return false;
488
+ }
489
+ if (hint & ERComponentHint.SkipClassMethod && isFunctionOfClassMethod(node.parent)) {
490
+ return false;
491
+ }
492
+ if (hint & ERComponentHint.SkipClassProperty && isFunctionOfClassProperty(node.parent)) {
493
+ return false;
494
+ }
495
+ const boundaryNode = AST8__namespace.findParentNode(
496
+ node,
497
+ AST8__namespace.isOneOf([
498
+ types.AST_NODE_TYPES.JSXExpressionContainer,
499
+ types.AST_NODE_TYPES.ArrowFunctionExpression,
500
+ types.AST_NODE_TYPES.FunctionExpression,
501
+ types.AST_NODE_TYPES.Property,
502
+ types.AST_NODE_TYPES.ClassBody
503
+ ])
504
+ );
505
+ return boundaryNode == null || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
460
506
  }
461
- function isComponentName(name) {
462
- return RE_COMPONENT_NAME.test(name);
507
+ function isFunctionOfClassMethod(node) {
508
+ return (node.type === types.AST_NODE_TYPES.FunctionExpression || node.type === types.AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === types.AST_NODE_TYPES.MethodDefinition;
463
509
  }
464
- function hasNoneOrValidComponentName(node, context) {
465
- const id = getFunctionComponentIdentifier(node, context);
466
- if (id == null) return true;
467
- const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
468
- return name != null && isComponentName(name);
510
+ function isFunctionOfClassProperty(node) {
511
+ return (node.type === types.AST_NODE_TYPES.FunctionExpression || node.type === types.AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === types.AST_NODE_TYPES.Property;
512
+ }
513
+ function isFunctionOfObjectMethod(node) {
514
+ return (node.type === types.AST_NODE_TYPES.FunctionExpression || node.type === types.AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === types.AST_NODE_TYPES.Property && node.parent.parent.type === types.AST_NODE_TYPES.ObjectExpression;
469
515
  }
470
516
 
471
517
  // src/component/component-collector.ts
@@ -483,7 +529,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
483
529
  const entry = functionEntries.at(-1);
484
530
  if (entry == null) return;
485
531
  if (!entry.isComponent) return functionEntries.pop();
486
- const shouldDrop = AST9__namespace.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
532
+ const shouldDrop = AST8__namespace.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
487
533
  return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3__namespace.isJSXValue(r.argument, jsxCtx, hint);
488
534
  });
489
535
  if (shouldDrop) {
@@ -510,7 +556,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
510
556
  const { body } = entry.node;
511
557
  const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX3__namespace.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
512
558
  if (!isComponent) return;
513
- const initPath = AST9__namespace.getFunctionInitPath(entry.node);
559
+ const initPath = AST8__namespace.getFunctionInitPath(entry.node);
514
560
  const id = getFunctionComponentIdentifier(entry.node, context);
515
561
  const name = getComponentNameFromIdentifier(id);
516
562
  const key = shared.getId();
@@ -551,7 +597,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
551
597
  const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX3__namespace.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
552
598
  if (!isComponent) return;
553
599
  entry.isComponent = true;
554
- const initPath = AST9__namespace.getFunctionInitPath(entry.node);
600
+ const initPath = AST8__namespace.getFunctionInitPath(entry.node);
555
601
  const id = getFunctionComponentIdentifier(entry.node, context);
556
602
  const name = getComponentNameFromIdentifier(id);
557
603
  components.set(entry.key, {
@@ -570,40 +616,12 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
570
616
  };
571
617
  return { ctx, listeners };
572
618
  }
573
- function hasValidHierarchy(node, context, hint) {
574
- if (isChildrenOfCreateElement(node, context) || isFunctionOfRenderMethod(node)) {
575
- return false;
576
- }
577
- if (hint & ERComponentHint.SkipMapCallback && AST9__namespace.isMapCallLoose(node.parent)) {
578
- return false;
579
- }
580
- if (hint & ERComponentHint.SkipObjectMethod && AST9__namespace.isFunctionOfObjectMethod(node.parent)) {
581
- return false;
582
- }
583
- if (hint & ERComponentHint.SkipClassMethod && AST9__namespace.isFunctionOfClassMethod(node.parent)) {
584
- return false;
585
- }
586
- if (hint & ERComponentHint.SkipClassProperty && AST9__namespace.isFunctionOfClassProperty(node.parent)) {
587
- return false;
588
- }
589
- const boundaryNode = AST9__namespace.findParentNode(
590
- node,
591
- AST9__namespace.isOneOf([
592
- types.AST_NODE_TYPES.JSXExpressionContainer,
593
- types.AST_NODE_TYPES.ArrowFunctionExpression,
594
- types.AST_NODE_TYPES.FunctionExpression,
595
- types.AST_NODE_TYPES.Property,
596
- types.AST_NODE_TYPES.ClassBody
597
- ])
598
- );
599
- return boundaryNode == null || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
600
- }
601
619
  function getComponentFlag(initPath) {
602
620
  let flag = ERComponentFlag.None;
603
- if (initPath != null && AST9__namespace.hasCallInFunctionInitPath("memo", initPath)) {
621
+ if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("memo", initPath)) {
604
622
  flag |= ERComponentFlag.Memo;
605
623
  }
606
- if (initPath != null && AST9__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
624
+ if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
607
625
  flag |= ERComponentFlag.ForwardRef;
608
626
  }
609
627
  return flag;
@@ -620,7 +638,7 @@ function useComponentCollectorLegacy() {
620
638
  if (!isClassComponent(node)) {
621
639
  return;
622
640
  }
623
- const id = AST9__namespace.getClassIdentifier(node);
641
+ const id = AST8__namespace.getClassIdentifier(node);
624
642
  const key = shared.getId();
625
643
  const flag = isPureComponent(node) ? ERComponentFlag.PureComponent : ERComponentFlag.None;
626
644
  components.set(
@@ -653,7 +671,7 @@ var ERPhaseRelevance = birecord__default.default({
653
671
  var isInversePhase = eff.dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
654
672
  function isRenderFunctionLoose(node, context) {
655
673
  const { body, parent } = node;
656
- if (AST9__namespace.getFunctionIdentifier(node)?.name.startsWith("render")) {
674
+ if (AST8__namespace.getFunctionIdentifier(node)?.name.startsWith("render")) {
657
675
  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");
658
676
  }
659
677
  return JSX3__namespace.isJSXValue(
@@ -668,7 +686,7 @@ function isRenderPropLoose(node, context) {
668
686
  if (node.name.type !== types.AST_NODE_TYPES.JSXIdentifier) {
669
687
  return false;
670
688
  }
671
- return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer && AST9__namespace.isFunction(node.value.expression) && isRenderFunctionLoose(node.value.expression, context);
689
+ return node.name.name.startsWith("render") && node.value?.type === types.AST_NODE_TYPES.JSXExpressionContainer && AST8__namespace.isFunction(node.value.expression) && isRenderFunctionLoose(node.value.expression, context);
672
690
  }
673
691
  function isDirectValueOfRenderPropertyLoose(node) {
674
692
  const matching = (node2) => {
@@ -680,7 +698,7 @@ function isDeclaredInRenderPropLoose(node) {
680
698
  if (isDirectValueOfRenderPropertyLoose(node)) {
681
699
  return true;
682
700
  }
683
- const parent = AST9__namespace.findParentNode(node, AST9__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
701
+ const parent = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
684
702
  if (parent?.type !== types.AST_NODE_TYPES.JSXAttribute) {
685
703
  return false;
686
704
  }
@@ -688,16 +706,16 @@ function isDeclaredInRenderPropLoose(node) {
688
706
  }
689
707
  function isThisSetState(node) {
690
708
  const { callee } = node;
691
- return callee.type === types.AST_NODE_TYPES.MemberExpression && AST9__namespace.isThisExpression(callee.object) && callee.property.type === types.AST_NODE_TYPES.Identifier && callee.property.name === "setState";
709
+ return callee.type === types.AST_NODE_TYPES.MemberExpression && AST8__namespace.isThisExpression(callee.object) && callee.property.type === types.AST_NODE_TYPES.Identifier && callee.property.name === "setState";
692
710
  }
693
711
  function isFunctionOfUseEffectSetup(node) {
694
712
  if (node == null) return eff._;
695
713
  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);
696
714
  }
697
715
  function isFunctionOfUseEffectCleanup(node) {
698
- const nearReturn = AST9__namespace.findParentNode(node, AST9__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
699
- const nearFunction = AST9__namespace.findParentNode(node, AST9__namespace.isFunction);
700
- const nearFunctionOfReturn = AST9__namespace.findParentNode(nearReturn, AST9__namespace.isFunction);
716
+ const nearReturn = AST8__namespace.findParentNode(node, AST8__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
717
+ const nearFunction = AST8__namespace.findParentNode(node, AST8__namespace.isFunction);
718
+ const nearFunctionOfReturn = AST8__namespace.findParentNode(nearReturn, AST8__namespace.isFunction);
701
719
  return nearFunction === nearFunctionOfReturn && isFunctionOfUseEffectSetup(nearFunction);
702
720
  }
703
721
 
@@ -711,6 +729,7 @@ exports.RE_HOOK_NAME = RE_HOOK_NAME;
711
729
  exports.getComponentNameFromIdentifier = getComponentNameFromIdentifier;
712
730
  exports.getFunctionComponentIdentifier = getFunctionComponentIdentifier;
713
731
  exports.hasNoneOrValidComponentName = hasNoneOrValidComponentName;
732
+ exports.hasValidHierarchy = hasValidHierarchy;
714
733
  exports.isCallFromReact = isCallFromReact;
715
734
  exports.isCallFromReactMember = isCallFromReactMember;
716
735
  exports.isChildrenCount = isChildrenCount;
@@ -743,7 +762,11 @@ exports.isDisplayNameAssignment = isDisplayNameAssignment;
743
762
  exports.isForwardRef = isForwardRef;
744
763
  exports.isForwardRefCall = isForwardRefCall;
745
764
  exports.isFromReact = isFromReact;
765
+ exports.isFromReactLoose = isFromReactLoose;
746
766
  exports.isFromReactMember = isFromReactMember;
767
+ exports.isFromReactMemberLoose = isFromReactMemberLoose;
768
+ exports.isFromReactMemberStrict = isFromReactMemberStrict;
769
+ exports.isFromReactStrict = isFromReactStrict;
747
770
  exports.isFunctionOfComponentDidMount = isFunctionOfComponentDidMount;
748
771
  exports.isFunctionOfComponentWillUnmount = isFunctionOfComponentWillUnmount;
749
772
  exports.isFunctionOfRenderMethod = isFunctionOfRenderMethod;
package/dist/index.mjs CHANGED
@@ -1,24 +1,13 @@
1
- import * as AST9 from '@eslint-react/ast';
1
+ import * as AST8 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
- import { unsafeDecodeSettings, DEFAULT_ESLINT_REACT_SETTINGS, getId } from '@eslint-react/shared';
4
+ import { DEFAULT_ESLINT_REACT_SETTINGS, 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
7
  import { match, P } from 'ts-pattern';
8
8
  import birecord from 'birecord';
9
9
 
10
10
  // src/component/component-collector.ts
11
- var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
12
- "AssignmentExpression",
13
- "[type]",
14
- "[operator='=']",
15
- "[left.type='MemberExpression']",
16
- "[left.property.name='displayName']"
17
- ].join("");
18
- function isDisplayNameAssignment(node) {
19
- if (node == null) return false;
20
- return node.type === AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === AST_NODE_TYPES.MemberExpression && node.left.property.type === AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
21
- }
22
11
  function getRequireExpressionArguments(node) {
23
12
  return match(node).with({ type: AST_NODE_TYPES.CallExpression, arguments: P.select(), callee: { type: AST_NODE_TYPES.Identifier, name: "require" } }, identity).with({ type: AST_NODE_TYPES.MemberExpression, object: P.select() }, getRequireExpressionArguments).otherwise(() => _);
24
13
  }
@@ -37,7 +26,7 @@ function isInitializedFromReact(name, source, initialScope) {
37
26
  }
38
27
  const args = getRequireExpressionArguments(init);
39
28
  const arg0 = args?.[0];
40
- if (arg0 == null || !AST9.isStringLiteral(arg0)) {
29
+ if (arg0 == null || !AST8.isKindOfLiteral(arg0, "string")) {
41
30
  return false;
42
31
  }
43
32
  return arg0.value === source || arg0.value.startsWith(`${source}/`);
@@ -46,65 +35,85 @@ function isInitializedFromReact(name, source, initialScope) {
46
35
  }
47
36
 
48
37
  // src/utils/is-from-react.ts
38
+ var defaultImportSource = DEFAULT_ESLINT_REACT_SETTINGS.importSource;
39
+ function isFromReactLoose(node, name) {
40
+ if (node.type === AST_NODE_TYPES.MemberExpression) {
41
+ return node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === name;
42
+ }
43
+ return node.name === name;
44
+ }
45
+ function isFromReactStrict(node, name, importSource, initialScope) {
46
+ if (node.type === AST_NODE_TYPES.MemberExpression) {
47
+ return node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === name && isInitializedFromReact(node.object.name, importSource, initialScope);
48
+ }
49
+ if (node.name === name) {
50
+ return isInitializedFromReact(name, importSource, initialScope);
51
+ }
52
+ return false;
53
+ }
49
54
  function isFromReact(name) {
50
55
  return (node, context) => {
51
- const settings = unsafeDecodeSettings(context.settings);
52
- if (!settings.strictImportCheck) {
53
- if (node.type === AST_NODE_TYPES.MemberExpression) {
54
- return node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === name;
55
- }
56
- return node.name === name;
57
- }
58
- const importSource = settings.importSource ?? DEFAULT_ESLINT_REACT_SETTINGS.importSource;
59
- const initialScope = context.sourceCode.getScope(node);
60
- if (node.type === AST_NODE_TYPES.MemberExpression) {
61
- return node.object.type === AST_NODE_TYPES.Identifier && node.property.type === AST_NODE_TYPES.Identifier && node.property.name === name && isInitializedFromReact(node.object.name, importSource, initialScope);
62
- }
63
- if (node.name === name) {
64
- return isInitializedFromReact(name, importSource, initialScope);
65
- }
66
- return false;
56
+ const { importSource = defaultImportSource, strictImportCheck = false } = unsafeDecodeSettings(context.settings);
57
+ if (!strictImportCheck) return isFromReactLoose(node, name);
58
+ return isFromReactStrict(node, name, importSource, context.sourceCode.getScope(node));
67
59
  };
68
60
  }
61
+ function isFromReactMemberLoose(node, memberName, name) {
62
+ const { object, property } = node;
63
+ if (property.type !== AST_NODE_TYPES.Identifier || property.name !== name) return false;
64
+ if (object.type === AST_NODE_TYPES.Identifier && object.name === memberName) return true;
65
+ if (object.type === AST_NODE_TYPES.MemberExpression && object.object.type === AST_NODE_TYPES.Identifier && object.property.type === AST_NODE_TYPES.Identifier) {
66
+ return object.property.name === memberName;
67
+ }
68
+ return false;
69
+ }
70
+ function isFromReactMemberStrict(node, memberName, name, importSource, initialScope) {
71
+ const { object, property } = node;
72
+ if (property.type !== AST_NODE_TYPES.Identifier || property.name !== name) {
73
+ return false;
74
+ }
75
+ if (object.type === AST_NODE_TYPES.Identifier && object.name === memberName) {
76
+ return isInitializedFromReact(object.name, importSource, initialScope);
77
+ }
78
+ if (object.type === AST_NODE_TYPES.MemberExpression && object.object.type === AST_NODE_TYPES.Identifier && isInitializedFromReact(object.object.name, importSource, initialScope) && object.property.type === AST_NODE_TYPES.Identifier) {
79
+ return object.property.name === memberName;
80
+ }
81
+ return false;
82
+ }
69
83
  function isFromReactMember(memberName, name) {
70
84
  return (node, context) => {
71
- const settings = unsafeDecodeSettings(context.settings);
72
- if (!settings.strictImportCheck) {
73
- if (node.property.type !== AST_NODE_TYPES.Identifier || node.property.name !== name) return false;
74
- if (node.object.type === AST_NODE_TYPES.Identifier && node.object.name === memberName) return true;
75
- if (node.object.type === AST_NODE_TYPES.MemberExpression && node.object.object.type === AST_NODE_TYPES.Identifier && node.object.property.type === AST_NODE_TYPES.Identifier) {
76
- return node.object.property.name === memberName;
77
- }
78
- return false;
79
- }
80
- const importSource = settings.importSource ?? DEFAULT_ESLINT_REACT_SETTINGS.importSource;
81
- const initialScope = context.sourceCode.getScope(node);
82
- if (node.property.type !== AST_NODE_TYPES.Identifier || node.property.name !== name) {
83
- return false;
84
- }
85
- if (node.object.type === AST_NODE_TYPES.Identifier && node.object.name === memberName) {
86
- return isInitializedFromReact(node.object.name, importSource, initialScope);
87
- }
88
- if (node.object.type === AST_NODE_TYPES.MemberExpression && node.object.object.type === AST_NODE_TYPES.Identifier && isInitializedFromReact(node.object.object.name, importSource, initialScope) && node.object.property.type === AST_NODE_TYPES.Identifier) {
89
- return node.object.property.name === memberName;
90
- }
91
- return false;
85
+ const { importSource = defaultImportSource, strictImportCheck = false } = unsafeDecodeSettings(context.settings);
86
+ if (!strictImportCheck) return isFromReactMemberLoose(node, memberName, name);
87
+ return isFromReactMemberStrict(node, memberName, name, importSource, context.sourceCode.getScope(node));
92
88
  };
93
89
  }
90
+
91
+ // src/utils/is-call-from-react.ts
94
92
  function isCallFromReact(name) {
95
93
  return dual(2, (node, context) => {
96
94
  if (node.type !== AST_NODE_TYPES.CallExpression) return false;
97
- if (!AST9.isOneOf([AST_NODE_TYPES.Identifier, AST_NODE_TYPES.MemberExpression])(node.callee)) return false;
95
+ if (!AST8.isOneOf([AST_NODE_TYPES.Identifier, AST_NODE_TYPES.MemberExpression])(node.callee)) return false;
98
96
  return isFromReact(name)(node.callee, context);
99
97
  });
100
98
  }
101
99
  function isCallFromReactMember(pragmaMemberName, name) {
102
100
  return dual(2, (node, context) => {
103
101
  if (node.type !== AST_NODE_TYPES.CallExpression) return false;
104
- if (!AST9.is(AST_NODE_TYPES.MemberExpression)(node.callee)) return false;
102
+ if (!AST8.is(AST_NODE_TYPES.MemberExpression)(node.callee)) return false;
105
103
  return isFromReactMember(pragmaMemberName, name)(node.callee, context);
106
104
  });
107
105
  }
106
+ var DISPLAY_NAME_ASSIGNMENT_SELECTOR = [
107
+ "AssignmentExpression",
108
+ "[type]",
109
+ "[operator='=']",
110
+ "[left.type='MemberExpression']",
111
+ "[left.property.name='displayName']"
112
+ ].join("");
113
+ function isDisplayNameAssignment(node) {
114
+ if (node == null) return false;
115
+ return node.type === AST_NODE_TYPES.AssignmentExpression && node.operator === "=" && node.left.type === AST_NODE_TYPES.MemberExpression && node.left.property.type === AST_NODE_TYPES.Identifier && node.left.property.name === "displayName";
116
+ }
108
117
 
109
118
  // src/utils/is-react-api.ts
110
119
  function isReactAPIWithName(name, member) {
@@ -136,21 +145,6 @@ var isCreateRefCall = isReactAPICallWithName("createRef");
136
145
  var isForwardRefCall = isReactAPICallWithName("forwardRef");
137
146
  var isMemoCall = isReactAPICallWithName("memo");
138
147
 
139
- // src/element/hierarchy.ts
140
- function isInsideCreateElementProps(node, context) {
141
- const call = AST9.findParentNode(node, isCreateElementCall(context));
142
- if (call == null) return false;
143
- const prop = AST9.findParentNode(node, AST9.is(AST_NODE_TYPES.ObjectExpression));
144
- if (prop == null) return false;
145
- return prop === call.arguments[1];
146
- }
147
- function isChildrenOfCreateElement(node, context) {
148
- const parent = node.parent;
149
- if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
150
- if (!isCreateElementCall(parent, context)) return false;
151
- return parent.arguments.slice(2).some((arg) => arg === node);
152
- }
153
-
154
148
  // src/hook/hook-name.ts
155
149
  var RE_HOOK_NAME = /^use[A-Z\d]/u;
156
150
  function isReactHookName(name) {
@@ -160,7 +154,7 @@ function isReactHookName(name) {
160
154
  // src/hook/is.ts
161
155
  function isReactHook(node) {
162
156
  if (node == null) return _;
163
- const id = AST9.getFunctionIdentifier(node);
157
+ const id = AST8.getFunctionIdentifier(node);
164
158
  return id?.name != null && isReactHookName(id.name);
165
159
  }
166
160
  function isReactHookCall(node) {
@@ -252,13 +246,13 @@ var isUseTransitionCall = flip(isReactHookCallWithName)("useTransition");
252
246
 
253
247
  // src/hook/hierarchy.ts
254
248
  function isInsideReactHook(node) {
255
- return isReactHook(AST9.findParentNode(node, AST9.isFunction));
249
+ return isReactHook(AST8.findParentNode(node, AST8.isFunction));
256
250
  }
257
251
  function useHookCollector() {
258
252
  const hooks = /* @__PURE__ */ new Map();
259
253
  const functionEntries = [];
260
254
  const onFunctionEnter = (node) => {
261
- const id = AST9.getFunctionIdentifier(node);
255
+ const id = AST8.getFunctionIdentifier(node);
262
256
  const key = getId();
263
257
  const name = id?.name;
264
258
  if (name != null && isReactHookName(name)) {
@@ -354,7 +348,7 @@ function isComponentWrapperCall(node, context) {
354
348
  return isMemoCall(node, context) || isForwardRefCall(node, context) || isReactHookCallWithNameLoose(node)("useCallback");
355
349
  }
356
350
  function getFunctionComponentIdentifier(node, context) {
357
- const functionId = AST9.getFunctionIdentifier(node);
351
+ const functionId = AST8.getFunctionIdentifier(node);
358
352
  if (functionId != null) {
359
353
  return functionId;
360
354
  }
@@ -367,6 +361,33 @@ function getFunctionComponentIdentifier(node, context) {
367
361
  }
368
362
  return _;
369
363
  }
364
+ var RE_COMPONENT_NAME = /^_?[A-Z]/u;
365
+ function getComponentNameFromIdentifier(node) {
366
+ if (node == null) return _;
367
+ return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
368
+ }
369
+ function isComponentName(name) {
370
+ return RE_COMPONENT_NAME.test(name);
371
+ }
372
+ function hasNoneOrValidComponentName(node, context) {
373
+ const id = getFunctionComponentIdentifier(node, context);
374
+ if (id == null) return true;
375
+ const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
376
+ return name != null && isComponentName(name);
377
+ }
378
+ function isInsideCreateElementProps(node, context) {
379
+ const call = AST8.findParentNode(node, isCreateElementCall(context));
380
+ if (call == null) return false;
381
+ const prop = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.ObjectExpression));
382
+ if (prop == null) return false;
383
+ return prop === call.arguments[1];
384
+ }
385
+ function isChildrenOfCreateElement(node, context) {
386
+ const parent = node.parent;
387
+ if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
388
+ if (!isCreateElementCall(parent, context)) return false;
389
+ return parent.arguments.slice(2).some((arg) => arg === node);
390
+ }
370
391
  function isClassComponent(node) {
371
392
  if ("superClass" in node && node.superClass != null) {
372
393
  const re = /^(?:Pure)?Component$/u;
@@ -394,28 +415,28 @@ function isPureComponent(node) {
394
415
 
395
416
  // src/component/component-lifecycle.ts
396
417
  function isComponentDidMount(node) {
397
- return AST9.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
418
+ return AST8.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
398
419
  }
399
420
  function isComponentWillUnmount(node) {
400
- return AST9.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
421
+ return AST8.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
401
422
  }
402
423
  function isComponentDidCatch(node) {
403
- return AST9.isMethodOrProperty(node) && !node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
424
+ return AST8.isMethodOrProperty(node) && !node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
404
425
  }
405
426
  function isGetDerivedStateFromError(node) {
406
- return AST9.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
427
+ return AST8.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
407
428
  }
408
429
  function isGetDerivedStateFromProps(node) {
409
- return AST9.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
430
+ return AST8.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
410
431
  }
411
432
  function isFunctionOfComponentDidMount(node) {
412
- return AST9.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
433
+ return AST8.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
413
434
  }
414
435
  function isFunctionOfComponentWillUnmount(node) {
415
- return AST9.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
436
+ return AST8.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
416
437
  }
417
438
  function isRenderMethodLike(node) {
418
- return AST9.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration;
439
+ return AST8.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration;
419
440
  }
420
441
  function isFunctionOfRenderMethod(node) {
421
442
  if (!isRenderMethodLike(node.parent)) {
@@ -424,21 +445,46 @@ function isFunctionOfRenderMethod(node) {
424
445
  return isClassComponent(node.parent.parent.parent);
425
446
  }
426
447
  function isInsideRenderMethod(node) {
427
- return AST9.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
448
+ return AST8.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
428
449
  }
429
- var RE_COMPONENT_NAME = /^_?[A-Z]/u;
430
- function getComponentNameFromIdentifier(node) {
431
- if (node == null) return _;
432
- return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
450
+
451
+ // src/component/hierarchy.ts
452
+ function hasValidHierarchy(node, context, hint) {
453
+ if (isChildrenOfCreateElement(node, context) || isFunctionOfRenderMethod(node)) {
454
+ return false;
455
+ }
456
+ if (hint & ERComponentHint.SkipMapCallback && AST8.isMapCallLoose(node.parent)) {
457
+ return false;
458
+ }
459
+ if (hint & ERComponentHint.SkipObjectMethod && isFunctionOfObjectMethod(node.parent)) {
460
+ return false;
461
+ }
462
+ if (hint & ERComponentHint.SkipClassMethod && isFunctionOfClassMethod(node.parent)) {
463
+ return false;
464
+ }
465
+ if (hint & ERComponentHint.SkipClassProperty && isFunctionOfClassProperty(node.parent)) {
466
+ return false;
467
+ }
468
+ const boundaryNode = AST8.findParentNode(
469
+ node,
470
+ AST8.isOneOf([
471
+ AST_NODE_TYPES.JSXExpressionContainer,
472
+ AST_NODE_TYPES.ArrowFunctionExpression,
473
+ AST_NODE_TYPES.FunctionExpression,
474
+ AST_NODE_TYPES.Property,
475
+ AST_NODE_TYPES.ClassBody
476
+ ])
477
+ );
478
+ return boundaryNode == null || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
433
479
  }
434
- function isComponentName(name) {
435
- return RE_COMPONENT_NAME.test(name);
480
+ function isFunctionOfClassMethod(node) {
481
+ return (node.type === AST_NODE_TYPES.FunctionExpression || node.type === AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === AST_NODE_TYPES.MethodDefinition;
436
482
  }
437
- function hasNoneOrValidComponentName(node, context) {
438
- const id = getFunctionComponentIdentifier(node, context);
439
- if (id == null) return true;
440
- const name = Array.isArray(id) ? id.at(-1)?.name : id.name;
441
- return name != null && isComponentName(name);
483
+ function isFunctionOfClassProperty(node) {
484
+ return (node.type === AST_NODE_TYPES.FunctionExpression || node.type === AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === AST_NODE_TYPES.Property;
485
+ }
486
+ function isFunctionOfObjectMethod(node) {
487
+ return (node.type === AST_NODE_TYPES.FunctionExpression || node.type === AST_NODE_TYPES.ArrowFunctionExpression) && node.parent.type === AST_NODE_TYPES.Property && node.parent.parent.type === AST_NODE_TYPES.ObjectExpression;
442
488
  }
443
489
 
444
490
  // src/component/component-collector.ts
@@ -456,7 +502,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
456
502
  const entry = functionEntries.at(-1);
457
503
  if (entry == null) return;
458
504
  if (!entry.isComponent) return functionEntries.pop();
459
- const shouldDrop = AST9.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
505
+ const shouldDrop = AST8.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
460
506
  return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3.isJSXValue(r.argument, jsxCtx, hint);
461
507
  });
462
508
  if (shouldDrop) {
@@ -483,7 +529,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
483
529
  const { body } = entry.node;
484
530
  const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX3.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
485
531
  if (!isComponent) return;
486
- const initPath = AST9.getFunctionInitPath(entry.node);
532
+ const initPath = AST8.getFunctionInitPath(entry.node);
487
533
  const id = getFunctionComponentIdentifier(entry.node, context);
488
534
  const name = getComponentNameFromIdentifier(id);
489
535
  const key = getId();
@@ -524,7 +570,7 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
524
570
  const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX3.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
525
571
  if (!isComponent) return;
526
572
  entry.isComponent = true;
527
- const initPath = AST9.getFunctionInitPath(entry.node);
573
+ const initPath = AST8.getFunctionInitPath(entry.node);
528
574
  const id = getFunctionComponentIdentifier(entry.node, context);
529
575
  const name = getComponentNameFromIdentifier(id);
530
576
  components.set(entry.key, {
@@ -543,40 +589,12 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options =
543
589
  };
544
590
  return { ctx, listeners };
545
591
  }
546
- function hasValidHierarchy(node, context, hint) {
547
- if (isChildrenOfCreateElement(node, context) || isFunctionOfRenderMethod(node)) {
548
- return false;
549
- }
550
- if (hint & ERComponentHint.SkipMapCallback && AST9.isMapCallLoose(node.parent)) {
551
- return false;
552
- }
553
- if (hint & ERComponentHint.SkipObjectMethod && AST9.isFunctionOfObjectMethod(node.parent)) {
554
- return false;
555
- }
556
- if (hint & ERComponentHint.SkipClassMethod && AST9.isFunctionOfClassMethod(node.parent)) {
557
- return false;
558
- }
559
- if (hint & ERComponentHint.SkipClassProperty && AST9.isFunctionOfClassProperty(node.parent)) {
560
- return false;
561
- }
562
- const boundaryNode = AST9.findParentNode(
563
- node,
564
- AST9.isOneOf([
565
- AST_NODE_TYPES.JSXExpressionContainer,
566
- AST_NODE_TYPES.ArrowFunctionExpression,
567
- AST_NODE_TYPES.FunctionExpression,
568
- AST_NODE_TYPES.Property,
569
- AST_NODE_TYPES.ClassBody
570
- ])
571
- );
572
- return boundaryNode == null || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
573
- }
574
592
  function getComponentFlag(initPath) {
575
593
  let flag = ERComponentFlag.None;
576
- if (initPath != null && AST9.hasCallInFunctionInitPath("memo", initPath)) {
594
+ if (initPath != null && AST8.hasCallInFunctionInitPath("memo", initPath)) {
577
595
  flag |= ERComponentFlag.Memo;
578
596
  }
579
- if (initPath != null && AST9.hasCallInFunctionInitPath("forwardRef", initPath)) {
597
+ if (initPath != null && AST8.hasCallInFunctionInitPath("forwardRef", initPath)) {
580
598
  flag |= ERComponentFlag.ForwardRef;
581
599
  }
582
600
  return flag;
@@ -593,7 +611,7 @@ function useComponentCollectorLegacy() {
593
611
  if (!isClassComponent(node)) {
594
612
  return;
595
613
  }
596
- const id = AST9.getClassIdentifier(node);
614
+ const id = AST8.getClassIdentifier(node);
597
615
  const key = getId();
598
616
  const flag = isPureComponent(node) ? ERComponentFlag.PureComponent : ERComponentFlag.None;
599
617
  components.set(
@@ -626,7 +644,7 @@ var ERPhaseRelevance = birecord({
626
644
  var isInversePhase = dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
627
645
  function isRenderFunctionLoose(node, context) {
628
646
  const { body, parent } = node;
629
- if (AST9.getFunctionIdentifier(node)?.name.startsWith("render")) {
647
+ if (AST8.getFunctionIdentifier(node)?.name.startsWith("render")) {
630
648
  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");
631
649
  }
632
650
  return JSX3.isJSXValue(
@@ -641,7 +659,7 @@ function isRenderPropLoose(node, context) {
641
659
  if (node.name.type !== AST_NODE_TYPES.JSXIdentifier) {
642
660
  return false;
643
661
  }
644
- return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && AST9.isFunction(node.value.expression) && isRenderFunctionLoose(node.value.expression, context);
662
+ return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && AST8.isFunction(node.value.expression) && isRenderFunctionLoose(node.value.expression, context);
645
663
  }
646
664
  function isDirectValueOfRenderPropertyLoose(node) {
647
665
  const matching = (node2) => {
@@ -653,7 +671,7 @@ function isDeclaredInRenderPropLoose(node) {
653
671
  if (isDirectValueOfRenderPropertyLoose(node)) {
654
672
  return true;
655
673
  }
656
- const parent = AST9.findParentNode(node, AST9.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
674
+ const parent = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
657
675
  if (parent?.type !== AST_NODE_TYPES.JSXAttribute) {
658
676
  return false;
659
677
  }
@@ -661,17 +679,17 @@ function isDeclaredInRenderPropLoose(node) {
661
679
  }
662
680
  function isThisSetState(node) {
663
681
  const { callee } = node;
664
- return callee.type === AST_NODE_TYPES.MemberExpression && AST9.isThisExpression(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
682
+ return callee.type === AST_NODE_TYPES.MemberExpression && AST8.isThisExpression(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
665
683
  }
666
684
  function isFunctionOfUseEffectSetup(node) {
667
685
  if (node == null) return _;
668
686
  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);
669
687
  }
670
688
  function isFunctionOfUseEffectCleanup(node) {
671
- const nearReturn = AST9.findParentNode(node, AST9.is(AST_NODE_TYPES.ReturnStatement));
672
- const nearFunction = AST9.findParentNode(node, AST9.isFunction);
673
- const nearFunctionOfReturn = AST9.findParentNode(nearReturn, AST9.isFunction);
689
+ const nearReturn = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.ReturnStatement));
690
+ const nearFunction = AST8.findParentNode(node, AST8.isFunction);
691
+ const nearFunctionOfReturn = AST8.findParentNode(nearReturn, AST8.isFunction);
674
692
  return nearFunction === nearFunctionOfReturn && isFunctionOfUseEffectSetup(nearFunction);
675
693
  }
676
694
 
677
- export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, ERComponentFlag, ERComponentHint, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isDisplayNameAssignment, isForwardRef, isForwardRefCall, isFromReact, isFromReactMember, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
695
+ export { DEFAULT_COMPONENT_HINT, DISPLAY_NAME_ASSIGNMENT_SELECTOR, ERComponentFlag, ERComponentHint, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, hasNoneOrValidComponentName, hasValidHierarchy, isCallFromReact, isCallFromReactMember, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentName, isComponentWillUnmount, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isDisplayNameAssignment, isForwardRef, isForwardRefCall, isFromReact, isFromReactLoose, isFromReactMember, isFromReactMemberLoose, isFromReactMemberStrict, isFromReactStrict, isFunctionOfComponentDidMount, isFunctionOfComponentWillUnmount, isFunctionOfRenderMethod, isFunctionOfUseEffectCleanup, isFunctionOfUseEffectSetup, isGetDerivedStateFromError, isGetDerivedStateFromProps, isInitializedFromReact, isInsideCreateElementProps, isInsideReactHook, isInsideRenderMethod, isInversePhase, isMemo, isMemoCall, isPureComponent, isReactAPICallWithName, isReactAPIWithName, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderMethodLike, isRenderPropLoose, isThisSetState, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/core",
3
- "version": "1.28.0-next.1",
3
+ "version": "1.28.0-next.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": {
@@ -41,11 +41,11 @@
41
41
  "@typescript-eslint/utils": "^8.25.0",
42
42
  "birecord": "^0.1.1",
43
43
  "ts-pattern": "^5.6.2",
44
- "@eslint-react/ast": "1.28.0-next.1",
45
- "@eslint-react/eff": "1.28.0-next.1",
46
- "@eslint-react/jsx": "1.28.0-next.1",
47
- "@eslint-react/shared": "1.28.0-next.1",
48
- "@eslint-react/var": "1.28.0-next.1"
44
+ "@eslint-react/ast": "1.28.0-next.3",
45
+ "@eslint-react/eff": "1.28.0-next.3",
46
+ "@eslint-react/shared": "1.28.0-next.3",
47
+ "@eslint-react/jsx": "1.28.0-next.3",
48
+ "@eslint-react/var": "1.28.0-next.3"
49
49
  },
50
50
  "devDependencies": {
51
51
  "tsup": "^8.3.6",