@eslint-react/core 2.0.0-next.4 → 2.0.0-next.44

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +32 -31
  2. package/dist/index.js +53 -15
  3. package/package.json +12 -12
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import { RuleContext } from '@eslint-react/kit';
2
2
  import { TSESTree } from '@typescript-eslint/types';
3
3
  import { ESLintUtils, TSESTree as TSESTree$1 } from '@typescript-eslint/utils';
4
4
  import * as AST from '@eslint-react/ast';
5
- import { _ } from '@eslint-react/eff';
5
+ import { unit } from '@eslint-react/eff';
6
6
  import * as birecord from 'birecord';
7
7
  import { Scope } from '@typescript-eslint/scope-manager';
8
8
  import * as VAR from '@eslint-react/var';
@@ -80,10 +80,10 @@ interface SemanticEntry {
80
80
  }
81
81
 
82
82
  interface SemanticNode {
83
- id: _ | TSESTree.Identifier | TSESTree.Identifier[];
83
+ id: unit | TSESTree.Identifier | TSESTree.Identifier[];
84
84
  key: string;
85
85
  kind: string;
86
- name: _ | string;
86
+ name: unit | string;
87
87
  node: TSESTree.Node;
88
88
  flag: bigint;
89
89
  hint: bigint;
@@ -100,23 +100,23 @@ declare const ComponentFlag: {
100
100
  };
101
101
 
102
102
  interface FunctionComponent extends SemanticNode {
103
- id: _ | TSESTree.Identifier | TSESTree.Identifier[];
103
+ id: unit | TSESTree.Identifier | TSESTree.Identifier[];
104
104
  kind: "function";
105
105
  node: AST.TSESTreeFunction;
106
106
  flag: ComponentFlag;
107
107
  hint: ComponentDetectionHint;
108
- initPath: _ | AST.FunctionInitPath;
108
+ initPath: unit | AST.FunctionInitPath;
109
109
  hookCalls: TSESTree.CallExpression[];
110
- displayName: _ | TSESTree.Expression;
110
+ displayName: unit | TSESTree.Expression;
111
111
  }
112
112
  interface ClassComponent extends SemanticNode {
113
- id: _ | TSESTree.Identifier;
113
+ id: unit | TSESTree.Identifier;
114
114
  kind: "class";
115
115
  node: AST.TSESTreeClass;
116
116
  flag: ComponentFlag;
117
117
  hint: ComponentDetectionHint;
118
118
  methods: AST.TSESTreeMethodOrProperty[];
119
- displayName: _ | TSESTree.Expression;
119
+ displayName: unit | TSESTree.Expression;
120
120
  }
121
121
  type Component = ClassComponent | FunctionComponent;
122
122
 
@@ -136,7 +136,7 @@ declare namespace useComponentCollector {
136
136
  ctx: {
137
137
  getAllComponents: (node: TSESTree.Program) => Map<string, FunctionComponent>;
138
138
  getCurrentEntries: () => FunctionEntry[];
139
- getCurrentEntry: () => FunctionEntry | _;
139
+ getCurrentEntry: () => FunctionEntry | unit;
140
140
  };
141
141
  listeners: ESLintUtils.RuleListener;
142
142
  };
@@ -178,7 +178,7 @@ declare function useComponentCollectorLegacy(): useComponentCollectorLegacy.Retu
178
178
  declare function isFunctionOfRenderMethod(node: AST.TSESTreeFunction): boolean;
179
179
  declare function isValidComponentDefinition(context: RuleContext, node: AST.TSESTreeFunction, hint: bigint): boolean;
180
180
 
181
- declare function getFunctionComponentId(context: RuleContext, node: AST.TSESTreeFunction): TSESTree.Identifier | TSESTree.Identifier[] | _;
181
+ declare function getFunctionComponentId(context: RuleContext, node: AST.TSESTreeFunction): TSESTree.Identifier | TSESTree.Identifier[] | unit;
182
182
 
183
183
  declare function getComponentFlagFromInitPath(initPath: FunctionComponent["initPath"]): bigint;
184
184
 
@@ -217,7 +217,7 @@ declare function isGetDerivedStateFromError(node: TSESTree.Node): node is AST.TS
217
217
 
218
218
  declare function isComponentName(name: string): boolean;
219
219
  declare function isComponentNameLoose(name: string): boolean;
220
- declare function getComponentNameFromId(id: TSESTree.Identifier | TSESTree.Identifier[] | _): string | undefined;
220
+ declare function getComponentNameFromId(id: TSESTree.Identifier | TSESTree.Identifier[] | unit): string | undefined;
221
221
  declare function hasNoneOrLooseComponentName(context: RuleContext, fn: AST.TSESTreeFunction): boolean;
222
222
 
223
223
  /**
@@ -332,7 +332,7 @@ declare function isComponentWrapperCallLoose(context: RuleContext, node: TSESTre
332
332
  type EffectKind = "useEffect" | "useLayoutEffect" | "useInsertionEffect";
333
333
 
334
334
  interface Hook extends SemanticNode {
335
- id: TSESTree.Identifier | _;
335
+ id: TSESTree.Identifier | unit;
336
336
  node: AST.TSESTreeFunction;
337
337
  name: string;
338
338
  hookCalls: TSESTree.CallExpression[];
@@ -348,17 +348,19 @@ declare namespace useHookCollector {
348
348
  }
349
349
  declare function useHookCollector(): useHookCollector.ReturnType;
350
350
 
351
- declare function isReactHook(node: AST.TSESTreeFunction | _): boolean;
351
+ declare function isReactHookId(id: TSESTree.Identifier | TSESTree.MemberExpression): boolean;
352
+
353
+ declare function isReactHook(node: AST.TSESTreeFunction | unit): boolean;
352
354
  /**
353
355
  * Check if the given node is a React Hook call by its name.
354
356
  * @param node The node to check.
355
357
  * @returns `true` if the node is a React Hook call, `false` otherwise.
356
358
  */
357
- declare function isReactHookCall(node: TSESTree.Node | _): boolean;
358
- declare function isReactHookCallWithName(context: RuleContext, node: TSESTree.Node | _): (name: string) => boolean;
359
- declare function isReactHookCallWithNameLoose(node: TSESTree.Node | _): (name: string) => boolean;
360
- declare function isReactHookCallWithNameAlias(context: RuleContext, name: string, alias?: _ | string[]): (node: TSESTree.CallExpression) => boolean;
361
- declare function isUseEffectCallLoose(node: TSESTree.Node | _): boolean;
359
+ declare function isReactHookCall(node: TSESTree.Node | unit): boolean;
360
+ declare function isReactHookCallWithName(context: RuleContext, node: TSESTree.Node | unit): (name: string) => boolean;
361
+ declare function isReactHookCallWithNameLoose(node: TSESTree.Node | unit): (name: string) => boolean;
362
+ declare function isReactHookCallWithNameAlias(context: RuleContext, name: string, alias?: unit | string[]): (node: TSESTree.CallExpression) => boolean;
363
+ declare function isUseEffectCallLoose(node: TSESTree.Node | unit): boolean;
362
364
  declare const isUseCall: (context: RuleContext, node: TSESTree.Node | undefined) => boolean;
363
365
  declare const isUseActionStateCall: (context: RuleContext, node: TSESTree.Node | undefined) => boolean;
364
366
  declare const isUseCallbackCall: (context: RuleContext, node: TSESTree.Node | undefined) => boolean;
@@ -379,8 +381,7 @@ declare const isUseStateCall: (context: RuleContext, node: TSESTree.Node | undef
379
381
  declare const isUseSyncExternalStoreCall: (context: RuleContext, node: TSESTree.Node | undefined) => boolean;
380
382
  declare const isUseTransitionCall: (context: RuleContext, node: TSESTree.Node | undefined) => boolean;
381
383
 
382
- type HookKind = "custom" | "useActionState" | "useCallback" | "useContext" | "useDebugValue" | "useDeferredValue" | "useEffect" | "useId" | "useImperativeHandle" | "useInsertionEffect" | "useLayoutEffect" | "useMemo" | "useOptimistic" | "useReducer" | "useRef" | "useState" | "useSyncExternalStore" | "useTransition";
383
-
384
+ declare const REACT_BUILTIN_HOOK_NAMES: readonly ["use", "useActionState", "useCallback", "useContext", "useDebugValue", "useDeferredValue", "useEffect", "useFormStatus", "useId", "useImperativeHandle", "useInsertionEffect", "useLayoutEffect", "useMemo", "useOptimistic", "useReducer", "useRef", "useState", "useSyncExternalStore", "useTransition"];
384
385
  /**
385
386
  * Catch all identifiers that begin with "use" followed by an uppercase Latin
386
387
  * character to exclude identifiers like "user".
@@ -397,7 +398,7 @@ declare function isReactHookName(name: string): boolean;
397
398
  * @param initialScope The initial scope to use for variable resolution
398
399
  * @returns The JSX attribute node or undefined
399
400
  */
400
- declare function getAttribute(context: RuleContext, name: string, attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], initialScope?: Scope): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | _;
401
+ declare function getAttribute(context: RuleContext, name: string, attributes: (TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute)[], initialScope?: Scope): TSESTree$1.JSXAttribute | TSESTree$1.JSXSpreadAttribute | unit;
401
402
 
402
403
  /**
403
404
  * Get the stringified name of a JSX attribute
@@ -440,7 +441,7 @@ declare const DEFAULT_JSX_DETECTION_HINT: bigint;
440
441
  * @param node The AST node to check
441
442
  * @returns `true` if the node is a `JSXText` or a `Literal` node
442
443
  */
443
- declare function isJsxText(node: TSESTree$1.Node | null | _): node is TSESTree$1.JSXText | TSESTree$1.Literal;
444
+ declare function isJsxText(node: TSESTree$1.Node | null | unit): node is TSESTree$1.JSXText | TSESTree$1.Literal;
444
445
  /**
445
446
  * Heuristic decision to determine if a node is a JSX-like node.
446
447
  * @param code The sourceCode object
@@ -451,7 +452,7 @@ declare function isJsxText(node: TSESTree$1.Node | null | _): node is TSESTree$1
451
452
  */
452
453
  declare function isJsxLike(code: {
453
454
  getScope: (node: TSESTree$1.Node) => Scope;
454
- }, node: TSESTree$1.Node | _ | null, hint?: JSXDetectionHint): boolean;
455
+ }, node: TSESTree$1.Node | unit | null, hint?: JSXDetectionHint): boolean;
455
456
 
456
457
  /**
457
458
  * Get the stringified type of a JSX element
@@ -471,12 +472,12 @@ declare function hasEveryAttribute(context: RuleContext, names: string[], attrib
471
472
  * @param test The test to apply to the parent attribute
472
473
  * @returns The parent attribute node or undefined
473
474
  */
474
- declare function findParentAttribute(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | _;
475
+ declare function findParentAttribute(node: TSESTree.Node, test?: (node: TSESTree.JSXAttribute) => boolean): TSESTree.JSXAttribute | unit;
475
476
 
476
477
  declare function isHostElement(context: RuleContext, node: TSESTree.Node): boolean;
477
478
  declare function isKeyedElement(context: RuleContext, node: TSESTree.Node, initialScope?: Scope): boolean;
478
- declare function isFragmentElement(context: RuleContext, node: TSESTree.Node | null | _, allowJSXFragment?: false): node is TSESTree.JSXElement;
479
- declare function isFragmentElement(context: RuleContext, node: TSESTree.Node | null | _, allowJSXFragment?: true): node is TSESTree.JSXElement | TSESTree.JSXFragment;
479
+ declare function isFragmentElement(context: RuleContext, node: TSESTree.Node | null | unit, allowJSXFragment?: false): node is TSESTree.JSXElement;
480
+ declare function isFragmentElement(context: RuleContext, node: TSESTree.Node | null | unit, allowJSXFragment?: true): node is TSESTree.JSXElement | TSESTree.JSXFragment;
480
481
 
481
482
  /**
482
483
  * Get the stringified representation of a JSX node
@@ -502,15 +503,15 @@ declare function isInstanceIdEqual(context: RuleContext, a: TSESTree.Node, b: TS
502
503
 
503
504
  declare namespace isReactAPI {
504
505
  type ReturnType = {
505
- (context: RuleContext, node: _ | null | TSESTree.Node): node is TSESTree.Identifier | TSESTree.MemberExpression;
506
- (context: RuleContext): (node: _ | null | TSESTree.Node) => node is TSESTree.MemberExpression | TSESTree.Identifier;
506
+ (context: RuleContext, node: unit | null | TSESTree.Node): node is TSESTree.Identifier | TSESTree.MemberExpression;
507
+ (context: RuleContext): (node: unit | null | TSESTree.Node) => node is TSESTree.MemberExpression | TSESTree.Identifier;
507
508
  };
508
509
  }
509
510
  declare function isReactAPI(api: string): isReactAPI.ReturnType;
510
511
  declare namespace isReactAPICall {
511
512
  type ReturnType = {
512
- (context: RuleContext, node: _ | null | TSESTree.Node): node is TSESTree.CallExpression;
513
- (context: RuleContext): (node: _ | null | TSESTree.Node) => node is TSESTree.CallExpression;
513
+ (context: RuleContext, node: unit | null | TSESTree.Node): node is TSESTree.CallExpression;
514
+ (context: RuleContext): (node: unit | null | TSESTree.Node) => node is TSESTree.CallExpression;
514
515
  };
515
516
  }
516
517
  declare function isReactAPICall(api: string): isReactAPICall.ReturnType;
@@ -541,4 +542,4 @@ declare const isForwardRefCall: isReactAPICall.ReturnType;
541
542
  declare const isMemoCall: isReactAPICall.ReturnType;
542
543
  declare const isLazyCall: isReactAPICall.ReturnType;
543
544
 
544
- export { type ClassComponent, type Component, ComponentDetectionHint, type ComponentEffectPhaseKind, ComponentFlag, type ComponentKind, type ComponentLifecyclePhaseKind, type ComponentPhaseKind, ComponentPhaseRelevance, type ComponentStateKind, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, type EffectKind, type FunctionComponent, type Hook, type HookKind, JSXDetectionHint, type SemanticEntry, type SemanticNode, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getComponentFlagFromInitPath, getComponentNameFromId, getElementType, getFunctionComponentId, getInstanceId, hasAnyAttribute, hasAttribute, hasEveryAttribute, hasNoneOrLooseComponentName, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFragmentElement, isFunctionOfRender, isFunctionOfRenderMethod, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHostElement, isInitializedFromReact, isInstanceIdEqual, isInversePhase, isJsxLike, isJsxText, isKeyedElement, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderLike, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, isValidComponentDefinition, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
545
+ export { type ClassComponent, type Component, ComponentDetectionHint, type ComponentEffectPhaseKind, ComponentFlag, type ComponentKind, type ComponentLifecyclePhaseKind, type ComponentPhaseKind, ComponentPhaseRelevance, type ComponentStateKind, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, type EffectKind, type FunctionComponent, type Hook, JSXDetectionHint, REACT_BUILTIN_HOOK_NAMES, type SemanticEntry, type SemanticNode, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getComponentFlagFromInitPath, getComponentNameFromId, getElementType, getFunctionComponentId, getInstanceId, hasAnyAttribute, hasAttribute, hasEveryAttribute, hasNoneOrLooseComponentName, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFragmentElement, isFunctionOfRender, isFunctionOfRenderMethod, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHostElement, isInitializedFromReact, isInstanceIdEqual, isInversePhase, isJsxLike, isJsxText, isKeyedElement, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookId, isReactHookName, isRenderFunctionLoose, isRenderLike, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, isValidComponentDefinition, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { AST_NODE_TYPES } from '@typescript-eslint/types';
2
2
  import * as AST14 from '@eslint-react/ast';
3
- import { flip, dual, constFalse, identity, constTrue, _ } from '@eslint-react/eff';
3
+ import { flip, dual, constFalse, identity, constTrue, unit } from '@eslint-react/eff';
4
4
  import { RegExp, Selector } from '@eslint-react/kit';
5
5
  import { coerceSettings, DEFAULT_ESLINT_REACT_SETTINGS, getId } from '@eslint-react/shared';
6
6
  import * as VAR3 from '@eslint-react/var';
@@ -12,7 +12,7 @@ function isReactAPI(api) {
12
12
  const func = (context, node) => {
13
13
  if (node == null) return false;
14
14
  const getText = (n) => context.sourceCode.getText(n);
15
- const name = AST14.toString(node, getText);
15
+ const name = AST14.toStringFormat(node, getText);
16
16
  if (name === api) return true;
17
17
  if (name.substring(name.indexOf(".") + 1) === api) return true;
18
18
  return false;
@@ -70,7 +70,7 @@ function getInstanceId(node, prev) {
70
70
  case (node.type === AST_NODE_TYPES.PropertyDefinition && node.value === prev):
71
71
  return node.key;
72
72
  case (node.type === AST_NODE_TYPES.BlockStatement || node.type === AST_NODE_TYPES.Program || node.parent === node):
73
- return _;
73
+ return unit;
74
74
  default:
75
75
  return getInstanceId(node.parent, node);
76
76
  }
@@ -108,6 +108,27 @@ function isInstanceIdEqual(context, a, b) {
108
108
  }
109
109
 
110
110
  // src/hook/hook-name.ts
111
+ var REACT_BUILTIN_HOOK_NAMES = [
112
+ "use",
113
+ "useActionState",
114
+ "useCallback",
115
+ "useContext",
116
+ "useDebugValue",
117
+ "useDeferredValue",
118
+ "useEffect",
119
+ "useFormStatus",
120
+ "useId",
121
+ "useImperativeHandle",
122
+ "useInsertionEffect",
123
+ "useLayoutEffect",
124
+ "useMemo",
125
+ "useOptimistic",
126
+ "useReducer",
127
+ "useRef",
128
+ "useState",
129
+ "useSyncExternalStore",
130
+ "useTransition"
131
+ ];
111
132
  function isReactHookName(name) {
112
133
  return name === "use" || /^use[A-Z0-9]/.test(name);
113
134
  }
@@ -266,6 +287,16 @@ function useHookCollector() {
266
287
  };
267
288
  return { ctx, listeners };
268
289
  }
290
+ function isReactHookId(id) {
291
+ switch (id.type) {
292
+ case AST_NODE_TYPES.Identifier:
293
+ return isReactHookName(id.name);
294
+ case AST_NODE_TYPES.MemberExpression:
295
+ return "name" in id.property && isReactHookName(id.property.name);
296
+ default:
297
+ return false;
298
+ }
299
+ }
269
300
  function stringifyJsx(node) {
270
301
  switch (node.type) {
271
302
  case AST_NODE_TYPES.JSXIdentifier:
@@ -401,6 +432,9 @@ function isJsxLike(code, node, hint = DEFAULT_JSX_DETECTION_HINT) {
401
432
  return !(hint & JSXDetectionHint.SkipStringLiteral);
402
433
  }
403
434
  case AST_NODE_TYPES.ArrayExpression: {
435
+ if (node.elements.length === 0) {
436
+ return !(hint & JSXDetectionHint.SkipEmptyArray);
437
+ }
404
438
  if (hint & JSXDetectionHint.StrictArray) {
405
439
  return node.elements.every((n) => isJsxLike(code, n, hint));
406
440
  }
@@ -633,7 +667,7 @@ function getFunctionComponentId(context, node) {
633
667
  if (parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCallLoose(context, parent) && parent.parent.type === AST_NODE_TYPES.CallExpression && isComponentWrapperCallLoose(context, parent.parent) && parent.parent.parent.type === AST_NODE_TYPES.VariableDeclarator && parent.parent.parent.id.type === AST_NODE_TYPES.Identifier) {
634
668
  return parent.parent.parent.id;
635
669
  }
636
- return _;
670
+ return unit;
637
671
  }
638
672
 
639
673
  // src/component/component-flag.ts
@@ -664,7 +698,7 @@ function isComponentNameLoose(name) {
664
698
  return RegExp.COMPONENT_NAME_LOOSE.test(name);
665
699
  }
666
700
  function getComponentNameFromId(id) {
667
- if (id == null) return _;
701
+ if (id == null) return unit;
668
702
  return Array.isArray(id) ? id.map((n) => n.name).join(".") : id.name;
669
703
  }
670
704
  function hasNoneOrLooseComponentName(context, fn) {
@@ -692,11 +726,15 @@ function useComponentCollector(context, options = {}) {
692
726
  const entry = functionEntries.at(-1);
693
727
  if (entry == null) return;
694
728
  if (!entry.isComponent) return functionEntries.pop();
695
- const shouldDrop = AST14.getNestedReturnStatements(entry.node.body).slice().reverse().some((r) => {
696
- return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !isJsxLike(context.sourceCode, r.argument, hint);
697
- });
698
- if (shouldDrop) {
699
- components.delete(entry.key);
729
+ const rets = AST14.getNestedReturnStatements(entry.node.body);
730
+ for (let i = rets.length - 1; i >= 0; i--) {
731
+ const ret = rets[i];
732
+ if (ret == null) continue;
733
+ const shouldDrop = context.sourceCode.getScope(ret).block === entry.node && ret.argument != null && !isJsxLike(context.sourceCode, ret.argument, hint);
734
+ if (shouldDrop) {
735
+ components.delete(entry.key);
736
+ break;
737
+ }
700
738
  }
701
739
  return functionEntries.pop();
702
740
  };
@@ -729,7 +767,7 @@ function useComponentCollector(context, options = {}) {
729
767
  kind: "function",
730
768
  name,
731
769
  node: entry.node,
732
- displayName: _,
770
+ displayName: unit,
733
771
  flag: getComponentFlagFromInitPath(initPath),
734
772
  hint,
735
773
  hookCalls: entry.hookCalls,
@@ -740,7 +778,7 @@ function useComponentCollector(context, options = {}) {
740
778
  [Selector.DISPLAY_NAME_ASSIGNMENT_EXPRESSION](node) {
741
779
  const { left, right } = node;
742
780
  if (left.type !== AST_NODE_TYPES.MemberExpression) return;
743
- const componentName = left.object.type === AST_NODE_TYPES.Identifier ? left.object.name : _;
781
+ const componentName = left.object.type === AST_NODE_TYPES.Identifier ? left.object.name : unit;
744
782
  const component = [...components.values()].findLast(({ name }) => name != null && name === componentName);
745
783
  if (component == null) return;
746
784
  component.displayName = right;
@@ -769,7 +807,7 @@ function useComponentCollector(context, options = {}) {
769
807
  kind: "function",
770
808
  name,
771
809
  node: entry.node,
772
- displayName: _,
810
+ displayName: unit,
773
811
  flag: getComponentFlagFromInitPath(initPath),
774
812
  hint,
775
813
  hookCalls: entry.hookCalls,
@@ -803,7 +841,7 @@ function useComponentCollectorLegacy() {
803
841
  name: id?.name,
804
842
  node,
805
843
  // TODO: Get displayName of class component
806
- displayName: _,
844
+ displayName: unit,
807
845
  flag,
808
846
  hint: 0n,
809
847
  // TODO: Get methods of class component
@@ -924,4 +962,4 @@ function isAssignmentToThisState(node) {
924
962
  return left.type === AST_NODE_TYPES.MemberExpression && AST14.isThisExpression(left.object) && AST14.getPropertyName(left.property) === "state";
925
963
  }
926
964
 
927
- export { ComponentDetectionHint, ComponentFlag, ComponentPhaseRelevance, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getComponentFlagFromInitPath, getComponentNameFromId, getElementType, getFunctionComponentId, getInstanceId, hasAnyAttribute, hasAttribute, hasEveryAttribute, hasNoneOrLooseComponentName, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFragmentElement, isFunctionOfRender, isFunctionOfRenderMethod, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHostElement, isInitializedFromReact, isInstanceIdEqual, isInversePhase, isJsxLike, isJsxText, isKeyedElement, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookName, isRenderFunctionLoose, isRenderLike, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, isValidComponentDefinition, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
965
+ export { ComponentDetectionHint, ComponentFlag, ComponentPhaseRelevance, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, JSXDetectionHint, REACT_BUILTIN_HOOK_NAMES, findParentAttribute, getAttribute, getAttributeName, getAttributeValue, getComponentFlagFromInitPath, getComponentNameFromId, getElementType, getFunctionComponentId, getInstanceId, hasAnyAttribute, hasAttribute, hasEveryAttribute, hasNoneOrLooseComponentName, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOfCreateElement, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isDeclaredInRenderPropLoose, isDirectValueOfRenderPropertyLoose, isForwardRef, isForwardRefCall, isFragmentElement, isFunctionOfRender, isFunctionOfRenderMethod, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHostElement, isInitializedFromReact, isInstanceIdEqual, isInversePhase, isJsxLike, isJsxText, isKeyedElement, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isReactHook, isReactHookCall, isReactHookCallWithName, isReactHookCallWithNameAlias, isReactHookCallWithNameLoose, isReactHookId, isReactHookName, isRenderFunctionLoose, isRenderLike, isRenderMethodLike, isRenderPropLoose, isShouldComponentUpdate, isThisSetState, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCallLoose, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseSyncExternalStoreCall, isUseTransitionCall, isValidComponentDefinition, stringifyJsx, useComponentCollector, useComponentCollectorLegacy, useHookCollector };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/core",
3
- "version": "2.0.0-next.4",
3
+ "version": "2.0.0-next.44",
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": {
@@ -27,20 +27,20 @@
27
27
  "./package.json"
28
28
  ],
29
29
  "dependencies": {
30
- "@typescript-eslint/scope-manager": "^8.30.1",
31
- "@typescript-eslint/type-utils": "^8.30.1",
32
- "@typescript-eslint/types": "^8.30.1",
33
- "@typescript-eslint/utils": "^8.30.1",
30
+ "@typescript-eslint/scope-manager": "^8.34.0",
31
+ "@typescript-eslint/type-utils": "^8.34.0",
32
+ "@typescript-eslint/types": "^8.34.0",
33
+ "@typescript-eslint/utils": "^8.34.0",
34
34
  "birecord": "^0.1.1",
35
- "ts-pattern": "^5.7.0",
36
- "@eslint-react/ast": "2.0.0-next.4",
37
- "@eslint-react/eff": "2.0.0-next.4",
38
- "@eslint-react/kit": "2.0.0-next.4",
39
- "@eslint-react/shared": "2.0.0-next.4",
40
- "@eslint-react/var": "2.0.0-next.4"
35
+ "ts-pattern": "^5.7.1",
36
+ "@eslint-react/ast": "2.0.0-next.44",
37
+ "@eslint-react/eff": "2.0.0-next.44",
38
+ "@eslint-react/shared": "2.0.0-next.44",
39
+ "@eslint-react/var": "2.0.0-next.44",
40
+ "@eslint-react/kit": "2.0.0-next.44"
41
41
  },
42
42
  "devDependencies": {
43
- "tsup": "^8.4.0",
43
+ "tsup": "^8.5.0",
44
44
  "@local/configs": "0.0.0"
45
45
  },
46
46
  "engines": {