@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 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
- declare function useComponentCollector(context: RuleContext, hint?: bigint): {
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
- declare function useComponentCollector(context: RuleContext, hint?: bigint): {
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 !== eff._) return [name, component.as];
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 === eff._) return [name, name];
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.findParentNodeGuard(node, isCreateElementCall(context));
168
- if (!call) return false;
169
- const prop = AST8__namespace.findParentNodeGuard(node, AST8__namespace.is(types.AST_NODE_TYPES.ObjectExpression));
170
- if (!prop) return false;
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 (!parent || parent.type !== types.AST_NODE_TYPES.CallExpression) return false;
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 === eff._) return eff._;
188
+ if (node == null) return eff._;
189
189
  const id2 = AST8__namespace.getFunctionIdentifier(node);
190
- return id2?.name !== eff._ && isReactHookName(id2.name);
190
+ return id2?.name != null && isReactHookName(id2.name);
191
191
  }
192
192
  function isReactHookCall(node) {
193
- if (node === eff._) return false;
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 === eff._) return eff.returnFalse;
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 === eff._) return eff.returnFalse;
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 === eff._) return false;
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.findParentNodeGuard(node, AST8__namespace.isFunction));
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 !== eff._ && isReactHookName(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 === eff._) {
324
+ if (fEntry?.key == null) {
325
325
  return;
326
326
  }
327
327
  const hook = hooks.get(fEntry.key);
328
- if (hook === eff._) {
328
+ if (hook == null) {
329
329
  return;
330
330
  }
331
- hooks.set(hook._, {
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 !!AST8__namespace.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent));
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 (!id2) return true;
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 !boundaryNode || boundaryNode.type !== types.AST_NODE_TYPES.JSXExpressionContainer;
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")(initPath)) {
478
+ if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("memo", initPath)) {
486
479
  flag |= ERFunctionComponentFlag.Memo;
487
480
  }
488
- if (initPath && AST8__namespace.hasCallInFunctionInitPath("forwardRef")(initPath)) {
481
+ if (initPath != null && AST8__namespace.hasCallInFunctionInitPath("forwardRef", initPath)) {
489
482
  flag |= ERFunctionComponentFlag.ForwardRef;
490
483
  }
491
484
  return flag;
492
485
  }
493
- function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
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 (!entry) return;
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 && !!r.argument && !JSX4__namespace.isJSXValue(r.argument, jsxCtx, hint);
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 (!entry) {
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 = id2 && getComponentNameFromIdentifier(id2);
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
- "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']"(node) {
557
- const { left, right } = node;
558
- const componentName = left.object.type === types.AST_NODE_TYPES.Identifier ? left.object.name : eff._;
559
- const component = [...components.values()].findLast(({ name }) => name != null && name === componentName);
560
- if (!component) {
561
- return;
562
- }
563
- components.set(component._, {
564
- ...component,
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
- const entry = getCurrentEntry();
573
- if (!entry) {
574
- return;
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
- functionEntries.pop();
577
- functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
578
- },
573
+ } : {},
579
574
  "ReturnStatement[type]"(node) {
580
575
  const entry = getCurrentEntry();
581
- if (!entry) {
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 = id2 && getComponentNameFromIdentifier(id2);
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 === eff._) return eff._;
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.findParentNodeGuard(node, AST8__namespace.is(types.AST_NODE_TYPES.ReturnStatement));
653
- const nearFunction = AST8__namespace.findParentNodeGuard(node, AST8__namespace.isFunction);
654
- const nearFunctionOfReturn = AST8__namespace.findParentNodeGuard(nearReturn, AST8__namespace.isFunction);
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) || !!node.parent && matching(node.parent);
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.findParentNodeGuard(node, AST8__namespace.is(types.AST_NODE_TYPES.JSXExpressionContainer))?.parent;
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 !== _) return [name, component.as];
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 === _) return [name, name];
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.findParentNodeGuard(node, isCreateElementCall(context));
144
- if (!call) return false;
145
- const prop = AST8.findParentNodeGuard(node, AST8.is(AST_NODE_TYPES.ObjectExpression));
146
- if (!prop) return false;
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 (!parent || parent.type !== AST_NODE_TYPES.CallExpression) return false;
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 === _) return _;
164
+ if (node == null) return _;
165
165
  const id2 = AST8.getFunctionIdentifier(node);
166
- return id2?.name !== _ && isReactHookName(id2.name);
166
+ return id2?.name != null && isReactHookName(id2.name);
167
167
  }
168
168
  function isReactHookCall(node) {
169
- if (node === _) return false;
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 === _) return returnFalse;
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 === _) return returnFalse;
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 === _) return false;
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.findParentNodeGuard(node, AST8.isFunction));
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 !== _ && isReactHookName(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
- hooks.set(hook._, {
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 !!AST8.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent));
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 (!id2) return true;
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 !boundaryNode || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
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")(initPath)) {
454
+ if (initPath != null && AST8.hasCallInFunctionInitPath("memo", initPath)) {
462
455
  flag |= ERFunctionComponentFlag.Memo;
463
456
  }
464
- if (initPath && AST8.hasCallInFunctionInitPath("forwardRef")(initPath)) {
457
+ if (initPath != null && AST8.hasCallInFunctionInitPath("forwardRef", initPath)) {
465
458
  flag |= ERFunctionComponentFlag.ForwardRef;
466
459
  }
467
460
  return flag;
468
461
  }
469
- function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
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 (!entry) return;
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 && !!r.argument && !JSX4.isJSXValue(r.argument, jsxCtx, hint);
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 (!entry) {
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 = id2 && getComponentNameFromIdentifier(id2);
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
- "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']"(node) {
533
- const { left, right } = node;
534
- const componentName = left.object.type === AST_NODE_TYPES.Identifier ? left.object.name : _;
535
- const component = [...components.values()].findLast(({ name }) => name != null && name === componentName);
536
- if (!component) {
537
- return;
538
- }
539
- components.set(component._, {
540
- ...component,
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
- const entry = getCurrentEntry();
549
- if (!entry) {
550
- return;
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
- functionEntries.pop();
553
- functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
554
- },
549
+ } : {},
555
550
  "ReturnStatement[type]"(node) {
556
551
  const entry = getCurrentEntry();
557
- if (!entry) {
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 = id2 && getComponentNameFromIdentifier(id2);
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 === _) return _;
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.findParentNodeGuard(node, AST8.is(AST_NODE_TYPES.ReturnStatement));
629
- const nearFunction = AST8.findParentNodeGuard(node, AST8.isFunction);
630
- const nearFunctionOfReturn = AST8.findParentNodeGuard(nearReturn, AST8.isFunction);
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) || !!node.parent && matching(node.parent);
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.findParentNodeGuard(node, AST8.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
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.0",
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/ast": "1.24.0-beta.0",
42
- "@eslint-react/eff": "1.24.0-beta.0",
43
- "@eslint-react/jsx": "1.24.0-beta.0",
44
- "@eslint-react/shared": "1.24.0-beta.0",
45
- "@eslint-react/types": "1.24.0-beta.0",
46
- "@eslint-react/var": "1.24.0-beta.0"
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",