@eslint-react/core 1.24.0-next.0 → 1.24.0-next.11

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.mjs CHANGED
@@ -1,30 +1,12 @@
1
1
  import * as AST8 from '@eslint-react/ast';
2
- import { flip, birecord, dual, _, returnFalse } from '@eslint-react/eff';
3
- import * as JSX4 from '@eslint-react/jsx';
2
+ import { flip, dual, _, returnFalse } from '@eslint-react/eff';
3
+ import * as JSX3 from '@eslint-react/jsx';
4
4
  import { AST_NODE_TYPES } from '@typescript-eslint/types';
5
- import * as VAR from '@eslint-react/var';
6
5
  import { unsafeDecodeSettings } from '@eslint-react/shared';
6
+ import * as VAR from '@eslint-react/var';
7
+ import birecord from 'birecord';
7
8
 
8
9
  // src/component/component-collector.ts
9
- function getElementNameAndRepresentName(node, context, polymorphicPropName, additionalComponents = []) {
10
- const name = JSX4.getElementName(node);
11
- if (name === name.toLowerCase()) return [name, name];
12
- const component = additionalComponents.findLast((c) => c.name === name || c.re.test(name));
13
- if (component !== _) return [name, component.as];
14
- if (polymorphicPropName == null) return [name, name];
15
- const initialScope = context.sourceCode.getScope(node);
16
- const polymorphicProp = JSX4.findPropInAttributes(
17
- polymorphicPropName,
18
- initialScope,
19
- node.attributes
20
- );
21
- if (polymorphicProp === _) return [name, name];
22
- const polymorphicName = VAR.toResolved(JSX4.getPropValue(polymorphicProp, initialScope)).value;
23
- if (typeof polymorphicName === "string") {
24
- return [name, polymorphicName];
25
- }
26
- return [name, name];
27
- }
28
10
 
29
11
  // src/utils/get-id.ts
30
12
  var id = 0n;
@@ -140,15 +122,15 @@ var isMemoCall = isReactAPICallWithName("memo");
140
122
 
141
123
  // src/element/hierarchy.ts
142
124
  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;
125
+ const call = AST8.findParentNode(node, isCreateElementCall(context));
126
+ if (call == null) return false;
127
+ const prop = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.ObjectExpression));
128
+ if (prop == null) return false;
147
129
  return prop === call.arguments[1];
148
130
  }
149
131
  function isChildrenOfCreateElement(node, context) {
150
132
  const parent = node.parent;
151
- if (!parent || parent.type !== AST_NODE_TYPES.CallExpression) return false;
133
+ if (parent == null || parent.type !== AST_NODE_TYPES.CallExpression) return false;
152
134
  if (!isCreateElementCall(parent, context)) return false;
153
135
  return parent.arguments.slice(2).some((arg) => arg === node);
154
136
  }
@@ -161,12 +143,12 @@ function isReactHookName(name) {
161
143
 
162
144
  // src/hook/is.ts
163
145
  function isReactHook(node) {
164
- if (node === _) return _;
146
+ if (node == null) return _;
165
147
  const id2 = AST8.getFunctionIdentifier(node);
166
- return id2?.name !== _ && isReactHookName(id2.name);
148
+ return id2?.name != null && isReactHookName(id2.name);
167
149
  }
168
150
  function isReactHookCall(node) {
169
- if (node === _) return false;
151
+ if (node == null) return false;
170
152
  if (node.type !== AST_NODE_TYPES.CallExpression) {
171
153
  return false;
172
154
  }
@@ -179,7 +161,7 @@ function isReactHookCall(node) {
179
161
  return false;
180
162
  }
181
163
  function isReactHookCallWithName(node, context) {
182
- if (node === _) return returnFalse;
164
+ if (node == null) return returnFalse;
183
165
  const settings = unsafeDecodeSettings(context.settings);
184
166
  return (name) => {
185
167
  const initialScope = context.sourceCode.getScope(node);
@@ -194,7 +176,7 @@ function isReactHookCallWithName(node, context) {
194
176
  };
195
177
  }
196
178
  function isReactHookCallWithNameLoose(node) {
197
- if (node === _) return returnFalse;
179
+ if (node == null) return returnFalse;
198
180
  return (name) => {
199
181
  switch (node.callee.type) {
200
182
  case AST_NODE_TYPES.Identifier:
@@ -221,7 +203,7 @@ function isReactHookCallWithNameAlias(name, context, alias) {
221
203
  };
222
204
  }
223
205
  function isUseEffectCallLoose(node) {
224
- if (node === _) return false;
206
+ if (node == null) return false;
225
207
  if (node.type !== AST_NODE_TYPES.CallExpression) {
226
208
  return false;
227
209
  }
@@ -252,7 +234,7 @@ var isUseTransitionCall = flip(isReactHookCallWithName)("useTransition");
252
234
 
253
235
  // src/hook/hierarchy.ts
254
236
  function isInsideReactHook(node) {
255
- return isReactHook(AST8.findParentNodeGuard(node, AST8.isFunction));
237
+ return isReactHook(AST8.findParentNode(node, AST8.isFunction));
256
238
  }
257
239
  function useHookCollector() {
258
240
  const hooks = /* @__PURE__ */ new Map();
@@ -260,12 +242,12 @@ function useHookCollector() {
260
242
  const onFunctionEnter = (node) => {
261
243
  const id2 = AST8.getFunctionIdentifier(node);
262
244
  const name = id2?.name;
263
- if (name !== _ && isReactHookName(name)) {
245
+ if (name != null && isReactHookName(name)) {
264
246
  const key = getId();
265
247
  fEntries.push({ key, node });
266
248
  hooks.set(key, {
267
- _: key,
268
249
  id: id2,
250
+ key,
269
251
  kind: "function",
270
252
  name,
271
253
  node,
@@ -297,26 +279,20 @@ function useHookCollector() {
297
279
  return;
298
280
  }
299
281
  const fEntry = fEntries.at(-1);
300
- if (fEntry?.key === _) {
282
+ if (fEntry?.key == null) {
301
283
  return;
302
284
  }
303
285
  const hook = hooks.get(fEntry.key);
304
- if (hook === _) {
286
+ if (hook == null) {
305
287
  return;
306
288
  }
307
- hooks.set(hook._, {
308
- ...hook,
309
- hookCalls: [
310
- ...hook.hookCalls,
311
- node
312
- ]
313
- });
289
+ hook.hookCalls.push(node);
314
290
  }
315
291
  };
316
292
  return { ctx, listeners };
317
293
  }
318
294
  var ERComponentHint = {
319
- ...JSX4.JSXValueHint,
295
+ ...JSX3.JSXValueHint,
320
296
  // 1n << 0n - 1n << 63n are reserved for JSXValueHint
321
297
  // Skip function component created by React.memo
322
298
  SkipMemo: 1n << 64n,
@@ -359,7 +335,7 @@ function isComponentWrapperCall(node, context) {
359
335
  }
360
336
  function getFunctionComponentIdentifier(node, context) {
361
337
  const functionId = AST8.getFunctionIdentifier(node);
362
- if (functionId) {
338
+ if (functionId != null) {
363
339
  return functionId;
364
340
  }
365
341
  const { parent } = node;
@@ -371,17 +347,8 @@ function getFunctionComponentIdentifier(node, context) {
371
347
  }
372
348
  return _;
373
349
  }
374
-
375
- // src/component/component-name.ts
376
- var RE_COMPONENT_NAME = /^_?[A-Z]/u;
377
- function getComponentNameFromIdentifier(node) {
378
- return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
379
- }
380
- function isComponentName(name) {
381
- return RE_COMPONENT_NAME.test(name);
382
- }
383
350
  function isClassComponent(node) {
384
- if ("superClass" in node && node.superClass) {
351
+ if ("superClass" in node && node.superClass != null) {
385
352
  const re = /^(?:Pure)?Component$/u;
386
353
  switch (true) {
387
354
  case node.superClass.type === AST_NODE_TYPES.Identifier:
@@ -393,7 +360,7 @@ function isClassComponent(node) {
393
360
  return false;
394
361
  }
395
362
  function isPureComponent(node) {
396
- if ("superClass" in node && node.superClass) {
363
+ if ("superClass" in node && node.superClass != null) {
397
364
  const re = /^PureComponent$/u;
398
365
  switch (true) {
399
366
  case node.superClass.type === AST_NODE_TYPES.Identifier:
@@ -405,9 +372,30 @@ function isPureComponent(node) {
405
372
  return false;
406
373
  }
407
374
 
408
- // src/component/component-render-method.ts
375
+ // src/component/component-lifecycle.ts
376
+ function isComponentDidMount(node) {
377
+ return AST8.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
378
+ }
379
+ function isComponentWillUnmount(node) {
380
+ return AST8.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
381
+ }
382
+ function isComponentDidCatch(node) {
383
+ return AST8.isMethodOrProperty(node) && !node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidCatch";
384
+ }
385
+ function isGetDerivedStateFromError(node) {
386
+ return AST8.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromError";
387
+ }
388
+ function isGetDerivedStateFromProps(node) {
389
+ return AST8.isMethodOrProperty(node) && node.static && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "getDerivedStateFromProps";
390
+ }
391
+ function isFunctionOfComponentDidMount(node) {
392
+ return AST8.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
393
+ }
394
+ function isFunctionOfComponentWillUnmount(node) {
395
+ return AST8.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
396
+ }
409
397
  function isRenderMethodLike(node) {
410
- return (node.type === AST_NODE_TYPES.MethodDefinition || node.type === AST_NODE_TYPES.PropertyDefinition) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration;
398
+ return AST8.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "render" && node.parent.parent.type === AST_NODE_TYPES.ClassDeclaration;
411
399
  }
412
400
  function isFunctionOfRenderMethod(node) {
413
401
  if (!isRenderMethodLike(node.parent)) {
@@ -416,13 +404,19 @@ function isFunctionOfRenderMethod(node) {
416
404
  return isClassComponent(node.parent.parent.parent);
417
405
  }
418
406
  function isInsideRenderMethod(node) {
419
- return !!AST8.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent));
407
+ return AST8.findParentNode(node, (node2) => isRenderMethodLike(node2) && isClassComponent(node2.parent.parent)) != null;
408
+ }
409
+ var RE_COMPONENT_NAME = /^_?[A-Z]/u;
410
+ function getComponentNameFromIdentifier(node) {
411
+ if (node == null) return _;
412
+ return Array.isArray(node) ? node.map((n) => n.name).join(".") : node.name;
413
+ }
414
+ function isComponentName(name) {
415
+ return RE_COMPONENT_NAME.test(name);
420
416
  }
421
-
422
- // src/component/misc.ts
423
417
  function hasNoneOrValidComponentName(node, context) {
424
418
  const id2 = getFunctionComponentIdentifier(node, context);
425
- if (!id2) return true;
419
+ if (id2 == null) return true;
426
420
  const name = Array.isArray(id2) ? id2.at(-1)?.name : id2.name;
427
421
  return name != null && isComponentName(name);
428
422
  }
@@ -454,19 +448,21 @@ function hasValidHierarchy(node, context, hint) {
454
448
  AST_NODE_TYPES.ClassBody
455
449
  ])
456
450
  );
457
- return !boundaryNode || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
451
+ return boundaryNode == null || boundaryNode.type !== AST_NODE_TYPES.JSXExpressionContainer;
458
452
  }
459
453
  function getComponentFlag(initPath) {
460
454
  let flag = ERFunctionComponentFlag.None;
461
- if (initPath && AST8.hasCallInFunctionInitPath("memo")(initPath)) {
455
+ if (initPath != null && AST8.hasCallInFunctionInitPath("memo", initPath)) {
462
456
  flag |= ERFunctionComponentFlag.Memo;
463
457
  }
464
- if (initPath && AST8.hasCallInFunctionInitPath("forwardRef")(initPath)) {
458
+ if (initPath != null && AST8.hasCallInFunctionInitPath("forwardRef", initPath)) {
465
459
  flag |= ERFunctionComponentFlag.ForwardRef;
466
460
  }
467
461
  return flag;
468
462
  }
469
- function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
463
+ var displayNameAssignmentSelector = "AssignmentExpression[type][operator='='][left.type='MemberExpression'][left.property.name='displayName']";
464
+ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT, options = {}) {
465
+ const { collectDisplayName = false, collectHookCalls = false } = options;
470
466
  const jsxCtx = { getScope: (node) => context.sourceCode.getScope(node) };
471
467
  const components = /* @__PURE__ */ new Map();
472
468
  const functionEntries = [];
@@ -477,12 +473,12 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
477
473
  };
478
474
  const onFunctionExit = () => {
479
475
  const entry = functionEntries.at(-1);
480
- if (!entry) return;
476
+ if (entry == null) return;
481
477
  if (!entry.isComponent) {
482
478
  return functionEntries.pop();
483
479
  }
484
480
  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);
481
+ return context.sourceCode.getScope(r).block === entry.node && r.argument != null && !JSX3.isJSXValue(r.argument, jsxCtx, hint);
486
482
  });
487
483
  if (shouldDrop) {
488
484
  components.delete(entry.key);
@@ -504,21 +500,21 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
504
500
  ":function[type]:exit": onFunctionExit,
505
501
  "ArrowFunctionExpression[type][body.type!='BlockStatement']"() {
506
502
  const entry = getCurrentEntry();
507
- if (!entry) {
503
+ if (entry == null) {
508
504
  return;
509
505
  }
510
506
  const { body } = entry.node;
511
- const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
507
+ const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX3.isJSXValue(body, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
512
508
  if (!isComponent) {
513
509
  return;
514
510
  }
515
511
  const initPath = AST8.getFunctionInitPath(entry.node);
516
512
  const id2 = getFunctionComponentIdentifier(entry.node, context);
517
- const name = id2 && getComponentNameFromIdentifier(id2);
513
+ const name = getComponentNameFromIdentifier(id2);
518
514
  const key = getId();
519
515
  components.set(key, {
520
- _: key,
521
516
  id: id2,
517
+ key,
522
518
  kind: "function",
523
519
  name,
524
520
  node: entry.node,
@@ -529,35 +525,35 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
529
525
  initPath
530
526
  });
531
527
  },
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;
528
+ ...collectDisplayName ? {
529
+ [displayNameAssignmentSelector](node) {
530
+ const { left, right } = node;
531
+ const componentName = left.object.type === AST_NODE_TYPES.Identifier ? left.object.name : _;
532
+ const component = [...components.values()].findLast(({ name }) => name != null && name === componentName);
533
+ if (component == null) {
534
+ return;
535
+ }
536
+ component.displayName = right;
547
537
  }
548
- const entry = getCurrentEntry();
549
- if (!entry) {
550
- return;
538
+ } : {},
539
+ ...collectHookCalls ? {
540
+ "CallExpression[type]:exit"(node) {
541
+ if (!isReactHookCall(node)) {
542
+ return;
543
+ }
544
+ const entry = getCurrentEntry();
545
+ if (entry == null) {
546
+ return;
547
+ }
548
+ entry.hookCalls.push(node);
551
549
  }
552
- functionEntries.pop();
553
- functionEntries.push({ ...entry, hookCalls: [...entry.hookCalls, node] });
554
- },
550
+ } : {},
555
551
  "ReturnStatement[type]"(node) {
556
552
  const entry = getCurrentEntry();
557
- if (!entry) {
553
+ if (entry == null) {
558
554
  return;
559
555
  }
560
- const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX4.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
556
+ const isComponent = hasNoneOrValidComponentName(entry.node, context) && JSX3.isJSXValue(node.argument, jsxCtx, hint) && hasValidHierarchy(entry.node, context, hint);
561
557
  if (!isComponent) {
562
558
  return;
563
559
  }
@@ -565,10 +561,10 @@ function useComponentCollector(context, hint = DEFAULT_COMPONENT_HINT) {
565
561
  functionEntries.push({ ...entry, isComponent });
566
562
  const initPath = AST8.getFunctionInitPath(entry.node);
567
563
  const id2 = getFunctionComponentIdentifier(entry.node, context);
568
- const name = id2 && getComponentNameFromIdentifier(id2);
564
+ const name = getComponentNameFromIdentifier(id2);
569
565
  components.set(entry.key, {
570
- _: entry.key,
571
566
  id: id2,
567
+ key: entry.key,
572
568
  kind: "function",
573
569
  name,
574
570
  node: entry.node,
@@ -600,8 +596,8 @@ function useComponentCollectorLegacy() {
600
596
  components.set(
601
597
  key,
602
598
  {
603
- _: key,
604
599
  id: id2,
600
+ key,
605
601
  kind: "class",
606
602
  name: id2?.name,
607
603
  node,
@@ -620,60 +616,22 @@ function useComponentCollectorLegacy() {
620
616
  };
621
617
  return { ctx, listeners };
622
618
  }
623
- function isSetupFunction(node) {
624
- if (node === _) return _;
625
- 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
- }
627
- 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);
631
- return nearFunction === nearFunctionOfReturn && isSetupFunction(nearFunction);
632
- }
633
- function isComponentDidMount(node) {
634
- return AST8.isOneOf([AST_NODE_TYPES.MethodDefinition, AST_NODE_TYPES.PropertyDefinition])(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentDidMount";
635
- }
636
- function isComponentWillUnmount(node) {
637
- return AST8.isOneOf([AST_NODE_TYPES.MethodDefinition, AST_NODE_TYPES.PropertyDefinition])(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "componentWillUnmount";
638
- }
639
- function isComponentDidMountFunction(node) {
640
- return AST8.isFunction(node) && isComponentDidMount(node.parent) && node.parent.value === node;
641
- }
642
- function isComponentWillUnmountFunction(node) {
643
- return AST8.isFunction(node) && isComponentWillUnmount(node.parent) && node.parent.value === node;
644
- }
645
619
  var ERPhaseRelevance = birecord({
646
620
  mount: "unmount",
647
621
  setup: "cleanup"
648
622
  });
649
623
  var isInversePhase = dual(2, (a, b) => ERPhaseRelevance.get(a) === b);
650
- function isDirectValueOfRenderPropertyLoose(node) {
651
- const matching = (node2) => {
652
- return node2.type === AST_NODE_TYPES.Property && node2.key.type === AST_NODE_TYPES.Identifier && node2.key.name.startsWith("render");
653
- };
654
- return matching(node) || !!node.parent && matching(node.parent);
655
- }
656
- function isDeclaredInRenderPropLoose(node) {
657
- if (isDirectValueOfRenderPropertyLoose(node)) {
658
- return true;
659
- }
660
- const parent = AST8.findParentNodeGuard(node, AST8.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
661
- if (parent?.type !== AST_NODE_TYPES.JSXAttribute) {
662
- return false;
663
- }
664
- return parent.name.type === AST_NODE_TYPES.JSXIdentifier && parent.name.name.startsWith("render");
665
- }
666
624
  function isRenderFunctionLoose(node, context) {
667
625
  const { body, parent } = node;
668
626
  if (AST8.getFunctionIdentifier(node)?.name.startsWith("render")) {
669
627
  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");
670
628
  }
671
- return JSX4.isJSXValue(
629
+ return JSX3.isJSXValue(
672
630
  body,
673
631
  {
674
632
  getScope: (node2) => context.sourceCode.getScope(node2)
675
633
  },
676
- JSX4.JSXValueHint.SkipNullLiteral | JSX4.JSXValueHint.SkipUndefined | JSX4.JSXValueHint.StrictLogical | JSX4.JSXValueHint.StrictConditional
634
+ JSX3.JSXValueHint.SkipNullLiteral | JSX3.JSXValueHint.SkipUndefined | JSX3.JSXValueHint.StrictLogical | JSX3.JSXValueHint.StrictConditional
677
635
  );
678
636
  }
679
637
  function isRenderPropLoose(node, context) {
@@ -682,9 +640,35 @@ function isRenderPropLoose(node, context) {
682
640
  }
683
641
  return node.name.name.startsWith("render") && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && AST8.isFunction(node.value.expression) && isRenderFunctionLoose(node.value.expression, context);
684
642
  }
643
+ function isDirectValueOfRenderPropertyLoose(node) {
644
+ const matching = (node2) => {
645
+ return node2.type === AST_NODE_TYPES.Property && node2.key.type === AST_NODE_TYPES.Identifier && node2.key.name.startsWith("render");
646
+ };
647
+ return matching(node) || node.parent != null && matching(node.parent);
648
+ }
649
+ function isDeclaredInRenderPropLoose(node) {
650
+ if (isDirectValueOfRenderPropertyLoose(node)) {
651
+ return true;
652
+ }
653
+ const parent = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.JSXExpressionContainer))?.parent;
654
+ if (parent?.type !== AST_NODE_TYPES.JSXAttribute) {
655
+ return false;
656
+ }
657
+ return parent.name.type === AST_NODE_TYPES.JSXIdentifier && parent.name.name.startsWith("render");
658
+ }
685
659
  function isThisSetState(node) {
686
660
  const { callee } = node;
687
661
  return callee.type === AST_NODE_TYPES.MemberExpression && AST8.isThisExpression(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
688
662
  }
663
+ function isFunctionOfUseEffectSetup(node) {
664
+ if (node == null) return _;
665
+ 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);
666
+ }
667
+ function isFunctionOfUseEffectCleanup(node) {
668
+ const nearReturn = AST8.findParentNode(node, AST8.is(AST_NODE_TYPES.ReturnStatement));
669
+ const nearFunction = AST8.findParentNode(node, AST8.isFunction);
670
+ const nearFunctionOfReturn = AST8.findParentNode(nearReturn, AST8.isFunction);
671
+ return nearFunction === nearFunctionOfReturn && isFunctionOfUseEffectSetup(nearFunction);
672
+ }
689
673
 
690
- export { DEFAULT_COMPONENT_HINT, ERClassComponentFlag, ERComponentHint, ERFunctionComponentFlag, ERPhaseRelevance, 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 };
674
+ export { DEFAULT_COMPONENT_HINT, ERClassComponentFlag, ERComponentHint, ERFunctionComponentFlag, ERPhaseRelevance, RE_COMPONENT_NAME, RE_HOOK_NAME, getComponentNameFromIdentifier, getFunctionComponentIdentifier, getId, 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, 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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/core",
3
- "version": "1.24.0-next.0",
3
+ "version": "1.24.0-next.11",
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": {
@@ -33,17 +33,17 @@
33
33
  "./package.json"
34
34
  ],
35
35
  "dependencies": {
36
- "@typescript-eslint/scope-manager": "^8.19.1",
37
- "@typescript-eslint/type-utils": "^8.19.1",
38
- "@typescript-eslint/types": "^8.19.1",
39
- "@typescript-eslint/utils": "^8.19.1",
36
+ "@typescript-eslint/scope-manager": "^8.20.0",
37
+ "@typescript-eslint/type-utils": "^8.20.0",
38
+ "@typescript-eslint/types": "^8.20.0",
39
+ "@typescript-eslint/utils": "^8.20.0",
40
+ "birecord": "^0.1.1",
40
41
  "ts-pattern": "^5.6.0",
41
- "@eslint-react/ast": "1.24.0-next.0",
42
- "@eslint-react/eff": "1.24.0-next.0",
43
- "@eslint-react/shared": "1.24.0-next.0",
44
- "@eslint-react/jsx": "1.24.0-next.0",
45
- "@eslint-react/var": "1.24.0-next.0",
46
- "@eslint-react/types": "1.24.0-next.0"
42
+ "@eslint-react/ast": "1.24.0-next.11",
43
+ "@eslint-react/eff": "1.24.0-next.11",
44
+ "@eslint-react/jsx": "1.24.0-next.11",
45
+ "@eslint-react/var": "1.24.0-next.11",
46
+ "@eslint-react/shared": "1.24.0-next.11"
47
47
  },
48
48
  "devDependencies": {
49
49
  "tsup": "^8.3.5",