eslint-plugin-react-x 2.14.0-next.0 → 3.0.0-next.0

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 (2) hide show
  1. package/dist/index.js +1268 -526
  2. package/package.json +11 -11
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { DEFAULT_ESLINT_REACT_SETTINGS, WEBSITE_URL, coerceSettings, defineRuleListener, getConfigAdapters, getSettingsFromContext, report, toRegExp } from "@eslint-react/shared";
2
- import { AST_NODE_TYPES } from "@typescript-eslint/types";
2
+ import * as ast from "@eslint-react/ast";
3
+ import * as core from "@eslint-react/core";
3
4
  import { ESLintUtils } from "@typescript-eslint/utils";
4
5
  import { P, isMatching, match } from "ts-pattern";
5
6
  import ts from "typescript";
6
- import * as core from "@eslint-react/core";
7
- import * as ast from "@eslint-react/ast";
7
+ import { AST_NODE_TYPES } from "@typescript-eslint/types";
8
8
  import { findEnclosingAssignmentTarget, findVariable, getChildScopes, getObjectType, getVariableDefinitionNode, isAssignmentTargetEqual } from "@eslint-react/var";
9
- import { constFalse, constTrue, flow, getOrElseUpdate, identity, unit } from "@eslint-react/eff";
9
+ import { DefinitionType } from "@typescript-eslint/scope-manager";
10
+ import { constFalse, constTrue, constVoid, flow, getOrElseUpdate, identity, not, unit } from "@eslint-react/eff";
10
11
  import { compare } from "compare-versions";
11
12
  import { getConstrainedTypeAtLocation, isTypeReadonly } from "@typescript-eslint/type-utils";
12
13
  import { isPropertyReadonlyInType, unionConstituents } from "ts-api-utils";
@@ -42,10 +43,8 @@ const rules$8 = {
42
43
  "react-x/no-duplicate-key": "off",
43
44
  "react-x/no-implicit-key": "off",
44
45
  "react-x/no-misused-capture-owner-stack": "off",
45
- "react-x/no-unnecessary-key": "off",
46
46
  "react-x/no-unnecessary-use-callback": "off",
47
47
  "react-x/no-unnecessary-use-memo": "off",
48
- "react-x/no-unnecessary-use-ref": "off",
49
48
  "react-x/no-unused-props": "off",
50
49
  "react-x/prefer-read-only-props": "off"
51
50
  };
@@ -67,7 +66,7 @@ const rules$7 = {
67
66
  //#endregion
68
67
  //#region package.json
69
68
  var name$6 = "eslint-plugin-react-x";
70
- var version = "2.14.0-next.0";
69
+ var version = "3.0.0-next.0";
71
70
 
72
71
  //#endregion
73
72
  //#region src/utils/create-rule.ts
@@ -220,9 +219,512 @@ function getTypeVariants(types) {
220
219
  return variants;
221
220
  }
222
221
 
222
+ //#endregion
223
+ //#region src/rules/component-hook-factories.ts
224
+ const RULE_NAME$63 = "component-hook-factories";
225
+ var component_hook_factories_default = createRule({
226
+ meta: {
227
+ type: "problem",
228
+ docs: { description: "Disallows higher order functions that define components or hooks inside them." },
229
+ messages: {
230
+ component: "Do not define component '{{name}}' inside a function. Components should be defined at the module level. Move it to the top level.",
231
+ hook: "Do not define hook '{{name}}' inside a function. Hooks should be defined at the module level. Move it to the top level."
232
+ },
233
+ schema: []
234
+ },
235
+ name: RULE_NAME$63,
236
+ create: create$63,
237
+ defaultOptions: []
238
+ });
239
+ function create$63(context) {
240
+ const hint = core.ComponentDetectionHint.DoNotIncludeJsxWithNumberValue | core.ComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | core.ComponentDetectionHint.DoNotIncludeJsxWithNullValue | core.ComponentDetectionHint.DoNotIncludeJsxWithStringValue | core.ComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | core.ComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx | core.ComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayPattern | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayExpression | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback;
241
+ const fCollector = core.useComponentCollector(context, { hint });
242
+ const cCollector = core.useComponentCollectorLegacy(context);
243
+ const hCollector = core.useHookCollector(context);
244
+ const reported = /* @__PURE__ */ new Set();
245
+ return defineRuleListener(fCollector.visitor, cCollector.visitor, hCollector.visitor, { "Program:exit"(program) {
246
+ const fComponents = [...fCollector.ctx.getAllComponents(program)];
247
+ const cComponents = [...cCollector.ctx.getAllComponents(program)];
248
+ const hooks = [...hCollector.ctx.getAllHooks(program)];
249
+ for (const { name, node } of fComponents) {
250
+ if (name == null) continue;
251
+ if (ast.findParentNode(node, ast.isFunction) == null) continue;
252
+ if (reported.has(node)) continue;
253
+ context.report({
254
+ messageId: "component",
255
+ node,
256
+ data: { name }
257
+ });
258
+ reported.add(node);
259
+ }
260
+ for (const { name = "unknown", node } of cComponents) {
261
+ if (ast.findParentNode(node, ast.isFunction) == null) continue;
262
+ context.report({
263
+ messageId: "component",
264
+ node,
265
+ data: { name }
266
+ });
267
+ }
268
+ for (const { name, node } of hooks) {
269
+ if (ast.findParentNode(node, ast.isFunction) == null) continue;
270
+ if (reported.has(node)) continue;
271
+ context.report({
272
+ messageId: "hook",
273
+ node,
274
+ data: { name }
275
+ });
276
+ reported.add(node);
277
+ }
278
+ } });
279
+ }
280
+
281
+ //#endregion
282
+ //#region src/rules/error-boundaries.ts
283
+ const RULE_NAME$62 = "error-boundaries";
284
+ var error_boundaries_default = createRule({
285
+ meta: {
286
+ type: "problem",
287
+ docs: { description: "Validates usage of Error Boundaries instead of try/catch for errors in child components." },
288
+ messages: {
289
+ tryCatchWithJsx: "Use an Error Boundary to catch errors in child components. Try/catch can't catch errors during React's rendering process.",
290
+ tryCatchWithUse: "Use an Error Boundary instead of try/catch around the 'use' hook. The 'use' hook suspends the component, and its errors can only be caught by Error Boundaries."
291
+ },
292
+ schema: []
293
+ },
294
+ name: RULE_NAME$62,
295
+ create: create$62,
296
+ defaultOptions: []
297
+ });
298
+ function create$62(context) {
299
+ if (!context.sourceCode.text.includes("try")) return {};
300
+ const { ctx, visitor } = core.useComponentCollector(context);
301
+ const reported = /* @__PURE__ */ new Set();
302
+ return defineRuleListener(visitor, {
303
+ CallExpression(node) {
304
+ if (!core.isUseCall(node)) return;
305
+ const stmt = ast.findParentNode(node, ast.is(AST_NODE_TYPES.TryStatement));
306
+ if (stmt != null && !reported.has(stmt)) {
307
+ context.report({
308
+ messageId: "tryCatchWithUse",
309
+ node
310
+ });
311
+ reported.add(stmt);
312
+ }
313
+ },
314
+ "Program:exit"(node) {
315
+ for (const { rets } of ctx.getAllComponents(node)) for (const ret of rets) {
316
+ if (ret == null) continue;
317
+ const stmt = ast.findParentNode(ret, ast.is(AST_NODE_TYPES.TryStatement));
318
+ if (stmt != null && !reported.has(stmt)) {
319
+ context.report({
320
+ messageId: "tryCatchWithJsx",
321
+ node: stmt
322
+ });
323
+ reported.add(stmt);
324
+ }
325
+ }
326
+ }
327
+ });
328
+ }
329
+
330
+ //#endregion
331
+ //#region src/rules/exhaustive-deps.ts
332
+ const RULE_NAME$61 = "exhaustive-deps";
333
+ /**
334
+ * Built-in hooks that accept dependency arrays.
335
+ * Maps hook name to the index of the callback argument.
336
+ */
337
+ const HOOKS_WITH_DEPS = {
338
+ useCallback: 0,
339
+ useEffect: 0,
340
+ useImperativeHandle: 1,
341
+ useInsertionEffect: 0,
342
+ useLayoutEffect: 0,
343
+ useMemo: 0
344
+ };
345
+ /**
346
+ * Hooks whose return values (at specific destructuring indices) are stable.
347
+ */
348
+ const STABLE_HOOK_PATTERNS = {
349
+ useReducer: 1,
350
+ useRef: "all",
351
+ useState: 1,
352
+ useTransition: 1
353
+ };
354
+ /**
355
+ * Get the name of a hook from a call expression.
356
+ * @param node - the call expression node
357
+ */
358
+ function getHookName$1(node) {
359
+ if (node.callee.type === AST_NODE_TYPES.Identifier) return node.callee.name;
360
+ if (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier) return node.callee.property.name;
361
+ return null;
362
+ }
363
+ /**
364
+ * Check if a hook name is one of the built-in hooks with dependency arrays.
365
+ * @param name - the hook name to check
366
+ */
367
+ function isBuiltInHookWithDeps(name) {
368
+ return name in HOOKS_WITH_DEPS;
369
+ }
370
+ /**
371
+ * Get the callback argument index for a given hook.
372
+ * @param hookName - the hook name to look up
373
+ */
374
+ function getCallbackIndex(hookName) {
375
+ return HOOKS_WITH_DEPS[hookName] ?? 0;
376
+ }
377
+ /**
378
+ * Get the text representation of a member expression chain.
379
+ * Handles both regular (obj.prop) and optional (obj?.prop) member expressions.
380
+ * @param node - the member expression node
381
+ */
382
+ function getMemberExpressionText(node) {
383
+ const parts = [];
384
+ let current = node;
385
+ while (current.type === AST_NODE_TYPES.MemberExpression) {
386
+ const memberExpr = current;
387
+ if (memberExpr.computed) return null;
388
+ if (memberExpr.property.type !== AST_NODE_TYPES.Identifier) return null;
389
+ const sep = memberExpr.optional ? "?." : ".";
390
+ parts.unshift(`${sep}${memberExpr.property.name}`);
391
+ current = memberExpr.object;
392
+ }
393
+ if (current.type !== AST_NODE_TYPES.Identifier) return null;
394
+ parts.unshift(current.name);
395
+ return parts.join("");
396
+ }
397
+ /**
398
+ * Check if a variable is defined at module level (outside any function).
399
+ * @param variable - the variable to check
400
+ */
401
+ function isModuleLevelVariable(variable) {
402
+ for (const def of variable.defs) {
403
+ let node = def.name.parent;
404
+ while (node != null) {
405
+ if (ast.isFunction(node)) return false;
406
+ node = node.parent;
407
+ }
408
+ }
409
+ return true;
410
+ }
411
+ /**
412
+ * Check if a variable is an import.
413
+ * @param variable - the variable to check
414
+ */
415
+ function isImportVariable(variable) {
416
+ return variable.defs.length > 0 && variable.defs.every((def) => def.type === DefinitionType.ImportBinding);
417
+ }
418
+ /**
419
+ * Check if a variable is a stable value from a known React hook pattern.
420
+ * E.g., setState from useState, dispatch from useReducer, ref from useRef,
421
+ * startTransition from useTransition.
422
+ * @param variable - the variable to check
423
+ */
424
+ function isStableHookValue(variable) {
425
+ if (variable.defs.length === 0) return false;
426
+ const def = variable.defs[0];
427
+ if (def == null) return false;
428
+ if (def.type !== DefinitionType.Variable) return false;
429
+ const defNode = def.node;
430
+ const init = defNode.init;
431
+ if (init == null || init.type !== AST_NODE_TYPES.CallExpression) return false;
432
+ const hookName = getHookName$1(init);
433
+ if (hookName == null) return false;
434
+ const stablePattern = STABLE_HOOK_PATTERNS[hookName];
435
+ if (stablePattern == null) return false;
436
+ if (stablePattern === "all") return true;
437
+ const id = defNode.id;
438
+ if (id.type !== AST_NODE_TYPES.ArrayPattern) return false;
439
+ const stableIndex = stablePattern;
440
+ const element = id.elements[stableIndex];
441
+ if (element == null || element.type !== AST_NODE_TYPES.Identifier) return false;
442
+ return element.name === variable.name;
443
+ }
444
+ /**
445
+ * Check if a variable is stable (should not be required in dependency arrays).
446
+ * @param variable - the variable to check
447
+ */
448
+ function isStableVariable(variable) {
449
+ return isModuleLevelVariable(variable) || isImportVariable(variable) || isStableHookValue(variable);
450
+ }
451
+ /**
452
+ * Find the enclosing component or hook function for a node.
453
+ * @param node - the node to start searching from
454
+ */
455
+ function findComponentOrHookScope(node) {
456
+ let current = node.parent;
457
+ while (current != null) {
458
+ if (ast.isFunction(current)) {
459
+ const id = ast.getFunctionId(current);
460
+ if (id != null && id.type === AST_NODE_TYPES.Identifier) {
461
+ if (core.isHookName(id.name) || /^[A-Z]/.test(id.name)) return current;
462
+ }
463
+ if (id != null && id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) {
464
+ if (core.isHookName(id.property.name) || /^[A-Z]/.test(id.property.name)) return current;
465
+ }
466
+ }
467
+ current = current.parent;
468
+ }
469
+ return null;
470
+ }
471
+ /**
472
+ * Check if a variable is defined within the given function scope (reactive).
473
+ * @param variable - the variable to check
474
+ * @param scopeNode - the function scope to check against
475
+ */
476
+ function isDefinedInScope(variable, scopeNode) {
477
+ for (const def of variable.defs) {
478
+ let node = def.name;
479
+ for (;;) {
480
+ if (node === scopeNode) return true;
481
+ if (node.parent == null) break;
482
+ node = node.parent;
483
+ }
484
+ if (def.type === DefinitionType.Parameter) {
485
+ let paramNode = def.node;
486
+ for (;;) {
487
+ if (paramNode === scopeNode) return true;
488
+ if (paramNode.parent == null) break;
489
+ paramNode = paramNode.parent;
490
+ }
491
+ }
492
+ }
493
+ return false;
494
+ }
495
+ var exhaustive_deps_default = createRule({
496
+ meta: {
497
+ type: "problem",
498
+ docs: { description: "Enforces that React hook dependency arrays contain all reactive values used in the callback." },
499
+ fixable: "code",
500
+ messages: {
501
+ missingDeps: "React Hook '{{hookName}}' has missing dependencies: {{deps}}. Either include them or remove the dependency array.",
502
+ nonLiteralDeps: "React Hook '{{hookName}}' was passed a dependency list that is not an array literal. This means we can't statically verify whether you've passed the correct dependencies.",
503
+ unnecessaryDeps: "React Hook '{{hookName}}' has unnecessary dependencies: {{deps}}. Either exclude them or remove the dependency array."
504
+ },
505
+ schema: [{
506
+ type: "object",
507
+ additionalProperties: false,
508
+ properties: { additionalHooks: { type: "string" } }
509
+ }]
510
+ },
511
+ name: RULE_NAME$61,
512
+ create: create$61,
513
+ defaultOptions: [{}]
514
+ });
515
+ function create$61(context) {
516
+ const additionalHooks = context.options[0]?.additionalHooks;
517
+ const additionalHooksRegex = additionalHooks != null && additionalHooks.length > 0 ? new RegExp(additionalHooks) : null;
518
+ /** Collected hook calls for later analysis. */
519
+ const collectedHookCalls = [];
520
+ const getText = (n) => context.sourceCode.getText(n);
521
+ /**
522
+ * Check if a hook name matches the additionalHooks regex option.
523
+ * @param name - the hook name to check
524
+ */
525
+ function isAdditionalHook(name) {
526
+ return additionalHooksRegex != null && additionalHooksRegex.test(name);
527
+ }
528
+ /**
529
+ * Check if a call expression is a hook call that we should check for deps.
530
+ * @param node - the call expression to check
531
+ */
532
+ function isHookWithDeps(node) {
533
+ const name = getHookName$1(node);
534
+ if (name == null) return false;
535
+ return isBuiltInHookWithDeps(name) || isAdditionalHook(name);
536
+ }
537
+ /**
538
+ * Extract the callback and dependency array from a hook call.
539
+ * @param node - the hook call expression
540
+ * @param hookName - the resolved hook name
541
+ */
542
+ function extractCallbackAndDeps(node, hookName) {
543
+ const args = node.arguments;
544
+ if (args.length === 0) return null;
545
+ const callbackIndex = getCallbackIndex(hookName);
546
+ const callback = args[callbackIndex];
547
+ if (callback == null) return null;
548
+ const depsArgIndex = callbackIndex + 1;
549
+ if (args.length <= depsArgIndex) return null;
550
+ const depsArg = args[args.length - 1];
551
+ if (depsArg == null) return null;
552
+ if (depsArg.type === AST_NODE_TYPES.ArrayExpression) return {
553
+ callback,
554
+ depsArgNode: depsArg,
555
+ depsNode: depsArg
556
+ };
557
+ return {
558
+ callback,
559
+ depsArgNode: depsArg,
560
+ depsNode: null
561
+ };
562
+ }
563
+ /**
564
+ * Collect all reactive dependency candidates from a callback node.
565
+ * Walks the callback body, finds all identifier references and member expressions,
566
+ * resolves them via scope analysis, and classifies them as reactive or stable.
567
+ * @param callbackNode - the callback argument node
568
+ * @param componentScope - the enclosing component or hook function
569
+ */
570
+ function collectReactiveDeps(callbackNode, componentScope) {
571
+ const reactiveDeps = /* @__PURE__ */ new Set();
572
+ const callbackScope = context.sourceCode.getScope(callbackNode);
573
+ const references = collectScopeReferences(callbackScope);
574
+ for (const ref of references) {
575
+ const identifier = ref.identifier;
576
+ if (identifier.type !== AST_NODE_TYPES.Identifier) continue;
577
+ const memberExprText = getEnclosingMemberExpressionText(identifier);
578
+ if (memberExprText != null) {
579
+ const variable = findVariable(identifier.name, callbackScope);
580
+ if (variable == null) continue;
581
+ if (isStableVariable(variable)) continue;
582
+ if (!isDefinedInScope(variable, componentScope)) continue;
583
+ reactiveDeps.add(memberExprText);
584
+ continue;
585
+ }
586
+ const variable = findVariable(identifier.name, callbackScope);
587
+ if (variable == null) continue;
588
+ if (isStableVariable(variable)) continue;
589
+ if (!isDefinedInScope(variable, componentScope)) continue;
590
+ reactiveDeps.add(identifier.name);
591
+ }
592
+ return reactiveDeps;
593
+ }
594
+ /**
595
+ * Recursively collect all references from a scope and its child scopes,
596
+ * but stop at function boundaries that are not the callback itself.
597
+ * @param scope - the scope to collect references from
598
+ */
599
+ function collectScopeReferences(scope) {
600
+ const refs = [];
601
+ for (const ref of scope.references) {
602
+ if (ref.isWriteOnly()) continue;
603
+ refs.push(ref);
604
+ }
605
+ for (const childScope of scope.childScopes) refs.push(...collectScopeReferences(childScope));
606
+ return refs;
607
+ }
608
+ /**
609
+ * If an identifier is the root of a member expression chain,
610
+ * return the full text of that member expression.
611
+ * @param identifier - the identifier node to check
612
+ */
613
+ function getEnclosingMemberExpressionText(identifier) {
614
+ const { parent } = identifier;
615
+ if (parent.type !== AST_NODE_TYPES.MemberExpression) return null;
616
+ if (parent.object !== identifier) return null;
617
+ let outermost = parent;
618
+ let current = parent;
619
+ while (current.parent.type === AST_NODE_TYPES.MemberExpression && current.parent.object === current && !current.parent.computed) {
620
+ outermost = current.parent;
621
+ current = current.parent;
622
+ }
623
+ return getMemberExpressionText(outermost);
624
+ }
625
+ /**
626
+ * Get the set of declared dependencies from a dependency array node.
627
+ * @param depsNode - the array expression node
628
+ */
629
+ function getDeclaredDeps(depsNode) {
630
+ const deps = /* @__PURE__ */ new Set();
631
+ for (const element of depsNode.elements) {
632
+ if (element == null) continue;
633
+ if (element.type === AST_NODE_TYPES.SpreadElement) continue;
634
+ deps.add(getText(element));
635
+ }
636
+ return deps;
637
+ }
638
+ /**
639
+ * Generate a fix that produces a corrected dependency array.
640
+ * Removes unnecessary deps, adds missing deps, and sorts all alphabetically.
641
+ * @param depsNode - the dependency array node
642
+ * @param missing - set of missing dependency names
643
+ * @param unnecessary - set of unnecessary dependency names
644
+ */
645
+ function generateFix(depsNode, missing, unnecessary) {
646
+ return (fixer) => {
647
+ const allDeps = [...depsNode.elements.filter((el) => el != null && el.type !== AST_NODE_TYPES.SpreadElement).map((el) => getText(el)).filter((text) => !unnecessary.has(text)), ...missing].toSorted();
648
+ return fixer.replaceText(depsNode, `[${allDeps.join(", ")}]`);
649
+ };
650
+ }
651
+ /**
652
+ * Analyze a collected hook call and report missing/unnecessary dependencies.
653
+ * @param hookCall - the collected hook call to analyze
654
+ */
655
+ function analyzeHookCall(hookCall) {
656
+ const { node, callback, depsNode, hookName } = hookCall;
657
+ if (depsNode == null) return;
658
+ const componentScope = findComponentOrHookScope(node);
659
+ if (componentScope == null) return;
660
+ const reactiveDeps = collectReactiveDeps(callback, componentScope);
661
+ const declaredDeps = getDeclaredDeps(depsNode);
662
+ const missingDeps = /* @__PURE__ */ new Set();
663
+ for (const dep of reactiveDeps) if (!declaredDeps.has(dep)) missingDeps.add(dep);
664
+ const unnecessaryDeps = /* @__PURE__ */ new Set();
665
+ for (const dep of declaredDeps) if (!reactiveDeps.has(dep)) unnecessaryDeps.add(dep);
666
+ const hasMissing = missingDeps.size > 0;
667
+ const hasUnnecessary = unnecessaryDeps.size > 0;
668
+ if (!hasMissing && !hasUnnecessary) return;
669
+ const fix = generateFix(depsNode, missingDeps, unnecessaryDeps);
670
+ if (hasMissing) {
671
+ const depsList = [...missingDeps].toSorted().map((d) => `'${d}'`).join(", ");
672
+ context.report({
673
+ messageId: "missingDeps",
674
+ node: depsNode,
675
+ data: {
676
+ deps: depsList,
677
+ hookName
678
+ },
679
+ fix
680
+ });
681
+ }
682
+ if (hasUnnecessary) {
683
+ const depsList = [...unnecessaryDeps].toSorted().map((d) => `'${d}'`).join(", ");
684
+ context.report({
685
+ messageId: "unnecessaryDeps",
686
+ node: depsNode,
687
+ data: {
688
+ deps: depsList,
689
+ hookName
690
+ },
691
+ ...!hasMissing ? { fix } : {}
692
+ });
693
+ }
694
+ }
695
+ return {
696
+ CallExpression(node) {
697
+ if (!isHookWithDeps(node)) return;
698
+ const hookName = getHookName$1(node);
699
+ if (hookName == null) return;
700
+ const result = extractCallbackAndDeps(node, hookName);
701
+ if (result == null) return;
702
+ const { callback, depsArgNode, depsNode } = result;
703
+ if (depsNode == null && depsArgNode != null) {
704
+ context.report({
705
+ messageId: "nonLiteralDeps",
706
+ node: depsArgNode,
707
+ data: { hookName }
708
+ });
709
+ return;
710
+ }
711
+ collectedHookCalls.push({
712
+ node,
713
+ callback,
714
+ depsArgNode,
715
+ depsNode,
716
+ hookName
717
+ });
718
+ },
719
+ "Program:exit"() {
720
+ for (const hookCall of collectedHookCalls) analyzeHookCall(hookCall);
721
+ }
722
+ };
723
+ }
724
+
223
725
  //#endregion
224
726
  //#region src/rules/jsx-dollar.ts
225
- const RULE_NAME$63 = "jsx-dollar";
727
+ const RULE_NAME$60 = "jsx-dollar";
226
728
  var jsx_dollar_default = createRule({
227
729
  meta: {
228
730
  type: "problem",
@@ -235,11 +737,11 @@ var jsx_dollar_default = createRule({
235
737
  },
236
738
  schema: []
237
739
  },
238
- name: RULE_NAME$63,
239
- create: create$63,
740
+ name: RULE_NAME$60,
741
+ create: create$60,
240
742
  defaultOptions: []
241
743
  });
242
- function create$63(context) {
744
+ function create$60(context) {
243
745
  /**
244
746
  * Visitor function for JSXElement and JSXFragment nodes
245
747
  * @param node The JSXElement or JSXFragment node to be checked
@@ -280,7 +782,7 @@ function create$63(context) {
280
782
 
281
783
  //#endregion
282
784
  //#region src/rules/jsx-key-before-spread.ts
283
- const RULE_NAME$62 = "jsx-key-before-spread";
785
+ const RULE_NAME$59 = "jsx-key-before-spread";
284
786
  var jsx_key_before_spread_default = createRule({
285
787
  meta: {
286
788
  type: "problem",
@@ -288,11 +790,11 @@ var jsx_key_before_spread_default = createRule({
288
790
  messages: { default: "The 'key' prop must be placed before any spread props when using the new JSX transform." },
289
791
  schema: []
290
792
  },
291
- name: RULE_NAME$62,
292
- create: create$62,
793
+ name: RULE_NAME$59,
794
+ create: create$59,
293
795
  defaultOptions: []
294
796
  });
295
- function create$62(context) {
797
+ function create$59(context) {
296
798
  const { jsx } = {
297
799
  ...core.getJsxConfigFromContext(context),
298
800
  ...core.getJsxConfigFromAnnotation(context)
@@ -316,7 +818,7 @@ function create$62(context) {
316
818
 
317
819
  //#endregion
318
820
  //#region src/rules/jsx-no-comment-textnodes.ts
319
- const RULE_NAME$61 = "jsx-no-comment-textnodes";
821
+ const RULE_NAME$58 = "jsx-no-comment-textnodes";
320
822
  var jsx_no_comment_textnodes_default = createRule({
321
823
  meta: {
322
824
  type: "problem",
@@ -324,11 +826,11 @@ var jsx_no_comment_textnodes_default = createRule({
324
826
  messages: { default: "Possible misused comment in text node. Comments inside children section of tag should be placed inside braces." },
325
827
  schema: []
326
828
  },
327
- name: RULE_NAME$61,
328
- create: create$61,
829
+ name: RULE_NAME$58,
830
+ create: create$58,
329
831
  defaultOptions: []
330
832
  });
331
- function create$61(context) {
833
+ function create$58(context) {
332
834
  function hasCommentLike(node) {
333
835
  if (ast.isOneOf([AST_NODE_TYPES.JSXAttribute, AST_NODE_TYPES.JSXExpressionContainer])(node.parent)) return false;
334
836
  return /^\s*\/(?:\/|\*)/mu.test(context.sourceCode.getText(node));
@@ -349,7 +851,7 @@ function create$61(context) {
349
851
 
350
852
  //#endregion
351
853
  //#region src/rules/jsx-no-duplicate-props.ts
352
- const RULE_NAME$60 = "jsx-no-duplicate-props";
854
+ const RULE_NAME$57 = "jsx-no-duplicate-props";
353
855
  var jsx_no_duplicate_props_default = createRule({
354
856
  meta: {
355
857
  type: "problem",
@@ -357,11 +859,11 @@ var jsx_no_duplicate_props_default = createRule({
357
859
  messages: { default: "This JSX property is assigned multiple times." },
358
860
  schema: []
359
861
  },
360
- name: RULE_NAME$60,
361
- create: create$60,
862
+ name: RULE_NAME$57,
863
+ create: create$57,
362
864
  defaultOptions: []
363
865
  });
364
- function create$60(context) {
866
+ function create$57(context) {
365
867
  return { JSXOpeningElement(node) {
366
868
  const props = [];
367
869
  for (const attr of node.attributes) {
@@ -382,7 +884,7 @@ function create$60(context) {
382
884
 
383
885
  //#endregion
384
886
  //#region src/rules/jsx-no-iife.ts
385
- const RULE_NAME$59 = "jsx-no-iife";
887
+ const RULE_NAME$56 = "jsx-no-iife";
386
888
  var jsx_no_iife_default = createRule({
387
889
  meta: {
388
890
  type: "problem",
@@ -390,11 +892,11 @@ var jsx_no_iife_default = createRule({
390
892
  messages: { default: "Avoid using immediately-invoked function expressions in JSX." },
391
893
  schema: []
392
894
  },
393
- name: RULE_NAME$59,
394
- create: create$59,
895
+ name: RULE_NAME$56,
896
+ create: create$56,
395
897
  defaultOptions: []
396
898
  });
397
- function create$59(context) {
899
+ function create$56(context) {
398
900
  return {
399
901
  "JSXElement :function"(node) {
400
902
  if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) context.report({
@@ -413,7 +915,7 @@ function create$59(context) {
413
915
 
414
916
  //#endregion
415
917
  //#region src/rules/jsx-no-undef.ts
416
- const RULE_NAME$58 = "jsx-no-undef";
918
+ const RULE_NAME$55 = "jsx-no-undef";
417
919
  var jsx_no_undef_default = createRule({
418
920
  meta: {
419
921
  type: "problem",
@@ -421,11 +923,11 @@ var jsx_no_undef_default = createRule({
421
923
  messages: { default: "JSX variable '{{name}}' is not defined." },
422
924
  schema: []
423
925
  },
424
- name: RULE_NAME$58,
425
- create: create$58,
926
+ name: RULE_NAME$55,
927
+ create: create$55,
426
928
  defaultOptions: []
427
929
  });
428
- function create$58(context) {
930
+ function create$55(context) {
429
931
  return { JSXOpeningElement(node) {
430
932
  const name = match(node.name).with({ type: AST_NODE_TYPES.JSXIdentifier }, (n) => n.name).with({
431
933
  type: AST_NODE_TYPES.JSXMemberExpression,
@@ -444,8 +946,8 @@ function create$58(context) {
444
946
 
445
947
  //#endregion
446
948
  //#region src/rules/jsx-shorthand-boolean.ts
447
- const RULE_NAME$57 = "jsx-shorthand-boolean";
448
- const defaultOptions$4 = [1];
949
+ const RULE_NAME$54 = "jsx-shorthand-boolean";
950
+ const defaultOptions$3 = [1];
449
951
  const schema$3 = [{
450
952
  type: "integer",
451
953
  enum: [-1, 1]
@@ -458,12 +960,12 @@ var jsx_shorthand_boolean_default = createRule({
458
960
  messages: { default: "{{message}}" },
459
961
  schema: schema$3
460
962
  },
461
- name: RULE_NAME$57,
462
- create: create$57,
463
- defaultOptions: defaultOptions$4
963
+ name: RULE_NAME$54,
964
+ create: create$54,
965
+ defaultOptions: defaultOptions$3
464
966
  });
465
- function create$57(context) {
466
- const policy = context.options[0] ?? defaultOptions$4[0];
967
+ function create$54(context) {
968
+ const policy = context.options[0] ?? defaultOptions$3[0];
467
969
  return { JSXAttribute(node) {
468
970
  const { value } = node;
469
971
  const propName = core.getJsxAttributeName(context, node);
@@ -490,8 +992,8 @@ function create$57(context) {
490
992
 
491
993
  //#endregion
492
994
  //#region src/rules/jsx-shorthand-fragment.ts
493
- const RULE_NAME$56 = "jsx-shorthand-fragment";
494
- const defaultOptions$3 = [1];
995
+ const RULE_NAME$53 = "jsx-shorthand-fragment";
996
+ const defaultOptions$2 = [1];
495
997
  const schema$2 = [{
496
998
  type: "integer",
497
999
  enum: [-1, 1]
@@ -504,12 +1006,12 @@ var jsx_shorthand_fragment_default = createRule({
504
1006
  messages: { default: "{{message}}" },
505
1007
  schema: schema$2
506
1008
  },
507
- name: RULE_NAME$56,
508
- create: create$56,
509
- defaultOptions: defaultOptions$3
1009
+ name: RULE_NAME$53,
1010
+ create: create$53,
1011
+ defaultOptions: defaultOptions$2
510
1012
  });
511
- function create$56(context) {
512
- const policy = context.options[0] ?? defaultOptions$3[0];
1013
+ function create$53(context) {
1014
+ const policy = context.options[0] ?? defaultOptions$2[0];
513
1015
  const jsxConfig = {
514
1016
  ...core.getJsxConfigFromContext(context),
515
1017
  ...core.getJsxConfigFromAnnotation(context)
@@ -543,7 +1045,7 @@ function create$56(context) {
543
1045
 
544
1046
  //#endregion
545
1047
  //#region src/rules/jsx-uses-react.ts
546
- const RULE_NAME$55 = "jsx-uses-react";
1048
+ const RULE_NAME$52 = "jsx-uses-react";
547
1049
  var jsx_uses_react_default = createRule({
548
1050
  meta: {
549
1051
  type: "problem",
@@ -551,11 +1053,11 @@ var jsx_uses_react_default = createRule({
551
1053
  messages: { default: "Marked {{name}} as used." },
552
1054
  schema: []
553
1055
  },
554
- name: RULE_NAME$55,
555
- create: create$55,
1056
+ name: RULE_NAME$52,
1057
+ create: create$52,
556
1058
  defaultOptions: []
557
1059
  });
558
- function create$55(context) {
1060
+ function create$52(context) {
559
1061
  const { jsx, jsxFactory, jsxFragmentFactory } = {
560
1062
  ...core.getJsxConfigFromContext(context),
561
1063
  ...core.getJsxConfigFromAnnotation(context)
@@ -586,7 +1088,7 @@ function debugReport(context, node, name) {
586
1088
 
587
1089
  //#endregion
588
1090
  //#region src/rules/jsx-uses-vars.ts
589
- const RULE_NAME$54 = "jsx-uses-vars";
1091
+ const RULE_NAME$51 = "jsx-uses-vars";
590
1092
  var jsx_uses_vars_default = createRule({
591
1093
  meta: {
592
1094
  type: "problem",
@@ -594,11 +1096,11 @@ var jsx_uses_vars_default = createRule({
594
1096
  messages: { default: "An identifier in JSX is marked as used." },
595
1097
  schema: []
596
1098
  },
597
- name: RULE_NAME$54,
598
- create: create$54,
1099
+ name: RULE_NAME$51,
1100
+ create: create$51,
599
1101
  defaultOptions: []
600
1102
  });
601
- function create$54(context) {
1103
+ function create$51(context) {
602
1104
  return { JSXOpeningElement(node) {
603
1105
  switch (node.name.type) {
604
1106
  case AST_NODE_TYPES.JSXIdentifier:
@@ -616,7 +1118,7 @@ function create$54(context) {
616
1118
 
617
1119
  //#endregion
618
1120
  //#region src/rules/no-access-state-in-setstate.ts
619
- const RULE_NAME$53 = "no-access-state-in-setstate";
1121
+ const RULE_NAME$50 = "no-access-state-in-setstate";
620
1122
  function isKeyLiteral$2(node, key) {
621
1123
  return match(key).with({ type: AST_NODE_TYPES.Literal }, constTrue).with({
622
1124
  type: AST_NODE_TYPES.TemplateLiteral,
@@ -630,11 +1132,11 @@ var no_access_state_in_setstate_default = createRule({
630
1132
  messages: { default: "Do not access 'this.state' within 'setState'. Use the update function instead." },
631
1133
  schema: []
632
1134
  },
633
- name: RULE_NAME$53,
634
- create: create$53,
1135
+ name: RULE_NAME$50,
1136
+ create: create$50,
635
1137
  defaultOptions: []
636
1138
  });
637
- function create$53(context) {
1139
+ function create$50(context) {
638
1140
  if (!context.sourceCode.text.includes("setState")) return {};
639
1141
  const classStack = [];
640
1142
  const methodStack = [];
@@ -705,7 +1207,7 @@ function create$53(context) {
705
1207
 
706
1208
  //#endregion
707
1209
  //#region src/rules/no-array-index-key.ts
708
- const RULE_NAME$52 = "no-array-index-key";
1210
+ const RULE_NAME$49 = "no-array-index-key";
709
1211
  const REACT_CHILDREN_METHOD = ["forEach", "map"];
710
1212
  function getIndexParamPosition(methodName) {
711
1213
  switch (methodName) {
@@ -764,11 +1266,11 @@ var no_array_index_key_default = createRule({
764
1266
  messages: { default: "Do not use item index in the array as its key." },
765
1267
  schema: []
766
1268
  },
767
- name: RULE_NAME$52,
768
- create: create$52,
1269
+ name: RULE_NAME$49,
1270
+ create: create$49,
769
1271
  defaultOptions: []
770
1272
  });
771
- function create$52(context) {
1273
+ function create$49(context) {
772
1274
  const indexParamNames = [];
773
1275
  function isArrayIndex(node) {
774
1276
  return node.type === AST_NODE_TYPES.Identifier && indexParamNames.some((name) => name != null && name === node.name);
@@ -834,19 +1336,19 @@ function create$52(context) {
834
1336
 
835
1337
  //#endregion
836
1338
  //#region src/rules/no-children-count.ts
837
- const RULE_NAME$51 = "no-children-count";
1339
+ const RULE_NAME$48 = "no-children-count";
838
1340
  var no_children_count_default = createRule({
839
1341
  meta: {
840
1342
  type: "problem",
841
1343
  docs: { description: "Disallows the use of 'Children.count' from the 'react' package." },
842
1344
  messages: { default: "Using 'Children.count' is uncommon and can lead to fragile code. Use alternatives instead." },
843
1345
  schema: []
844
- },
845
- name: RULE_NAME$51,
846
- create: create$51,
1346
+ },
1347
+ name: RULE_NAME$48,
1348
+ create: create$48,
847
1349
  defaultOptions: []
848
1350
  });
849
- function create$51(context) {
1351
+ function create$48(context) {
850
1352
  return { MemberExpression(node) {
851
1353
  if (core.isChildrenCount(context, node)) context.report({
852
1354
  messageId: "default",
@@ -857,7 +1359,7 @@ function create$51(context) {
857
1359
 
858
1360
  //#endregion
859
1361
  //#region src/rules/no-children-for-each.ts
860
- const RULE_NAME$50 = "no-children-for-each";
1362
+ const RULE_NAME$47 = "no-children-for-each";
861
1363
  var no_children_for_each_default = createRule({
862
1364
  meta: {
863
1365
  type: "problem",
@@ -865,11 +1367,11 @@ var no_children_for_each_default = createRule({
865
1367
  messages: { default: "Using 'Children.forEach' is uncommon and can lead to fragile code. Use alternatives instead." },
866
1368
  schema: []
867
1369
  },
868
- name: RULE_NAME$50,
869
- create: create$50,
1370
+ name: RULE_NAME$47,
1371
+ create: create$47,
870
1372
  defaultOptions: []
871
1373
  });
872
- function create$50(context) {
1374
+ function create$47(context) {
873
1375
  return { MemberExpression(node) {
874
1376
  if (core.isChildrenForEach(context, node)) context.report({
875
1377
  messageId: "default",
@@ -880,7 +1382,7 @@ function create$50(context) {
880
1382
 
881
1383
  //#endregion
882
1384
  //#region src/rules/no-children-map.ts
883
- const RULE_NAME$49 = "no-children-map";
1385
+ const RULE_NAME$46 = "no-children-map";
884
1386
  var no_children_map_default = createRule({
885
1387
  meta: {
886
1388
  type: "problem",
@@ -888,11 +1390,11 @@ var no_children_map_default = createRule({
888
1390
  messages: { default: "Using 'Children.map' is uncommon and can lead to fragile code. Use alternatives instead." },
889
1391
  schema: []
890
1392
  },
891
- name: RULE_NAME$49,
892
- create: create$49,
1393
+ name: RULE_NAME$46,
1394
+ create: create$46,
893
1395
  defaultOptions: []
894
1396
  });
895
- function create$49(context) {
1397
+ function create$46(context) {
896
1398
  return { MemberExpression(node) {
897
1399
  if (core.isChildrenMap(context, node)) context.report({
898
1400
  messageId: "default",
@@ -903,7 +1405,7 @@ function create$49(context) {
903
1405
 
904
1406
  //#endregion
905
1407
  //#region src/rules/no-children-only.ts
906
- const RULE_NAME$48 = "no-children-only";
1408
+ const RULE_NAME$45 = "no-children-only";
907
1409
  var no_children_only_default = createRule({
908
1410
  meta: {
909
1411
  type: "problem",
@@ -911,11 +1413,11 @@ var no_children_only_default = createRule({
911
1413
  messages: { default: "Using 'Children.only' is uncommon and can lead to fragile code. Use alternatives instead." },
912
1414
  schema: []
913
1415
  },
914
- name: RULE_NAME$48,
915
- create: create$48,
1416
+ name: RULE_NAME$45,
1417
+ create: create$45,
916
1418
  defaultOptions: []
917
1419
  });
918
- function create$48(context) {
1420
+ function create$45(context) {
919
1421
  return { MemberExpression(node) {
920
1422
  if (core.isChildrenOnly(context, node)) context.report({
921
1423
  messageId: "default",
@@ -926,7 +1428,7 @@ function create$48(context) {
926
1428
 
927
1429
  //#endregion
928
1430
  //#region src/rules/no-children-prop.ts
929
- const RULE_NAME$47 = "no-children-prop";
1431
+ const RULE_NAME$44 = "no-children-prop";
930
1432
  var no_children_prop_default = createRule({
931
1433
  meta: {
932
1434
  type: "problem",
@@ -934,11 +1436,11 @@ var no_children_prop_default = createRule({
934
1436
  messages: { default: "Do not pass 'children' as props." },
935
1437
  schema: []
936
1438
  },
937
- name: RULE_NAME$47,
938
- create: create$47,
1439
+ name: RULE_NAME$44,
1440
+ create: create$44,
939
1441
  defaultOptions: []
940
1442
  });
941
- function create$47(context) {
1443
+ function create$44(context) {
942
1444
  return { JSXElement(node) {
943
1445
  const childrenProp = core.getJsxAttribute(context, node)("children");
944
1446
  if (childrenProp != null) context.report({
@@ -950,7 +1452,7 @@ function create$47(context) {
950
1452
 
951
1453
  //#endregion
952
1454
  //#region src/rules/no-children-to-array.ts
953
- const RULE_NAME$46 = "no-children-to-array";
1455
+ const RULE_NAME$43 = "no-children-to-array";
954
1456
  var no_children_to_array_default = createRule({
955
1457
  meta: {
956
1458
  type: "problem",
@@ -958,11 +1460,11 @@ var no_children_to_array_default = createRule({
958
1460
  messages: { default: "Using 'Children.toArray' is uncommon and can lead to fragile code. Use alternatives instead." },
959
1461
  schema: []
960
1462
  },
961
- name: RULE_NAME$46,
962
- create: create$46,
1463
+ name: RULE_NAME$43,
1464
+ create: create$43,
963
1465
  defaultOptions: []
964
1466
  });
965
- function create$46(context) {
1467
+ function create$43(context) {
966
1468
  return { MemberExpression(node) {
967
1469
  if (core.isChildrenToArray(context, node)) context.report({
968
1470
  messageId: "default",
@@ -973,7 +1475,7 @@ function create$46(context) {
973
1475
 
974
1476
  //#endregion
975
1477
  //#region src/rules/no-class-component.ts
976
- const RULE_NAME$45 = "no-class-component";
1478
+ const RULE_NAME$42 = "no-class-component";
977
1479
  var no_class_component_default = createRule({
978
1480
  meta: {
979
1481
  type: "problem",
@@ -981,11 +1483,11 @@ var no_class_component_default = createRule({
981
1483
  messages: { default: "Avoid using class components. Use function components instead." },
982
1484
  schema: []
983
1485
  },
984
- name: RULE_NAME$45,
985
- create: create$45,
1486
+ name: RULE_NAME$42,
1487
+ create: create$42,
986
1488
  defaultOptions: []
987
1489
  });
988
- function create$45(context) {
1490
+ function create$42(context) {
989
1491
  if (!context.sourceCode.text.includes("Component")) return {};
990
1492
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
991
1493
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1002,7 +1504,7 @@ function create$45(context) {
1002
1504
 
1003
1505
  //#endregion
1004
1506
  //#region src/rules/no-clone-element.ts
1005
- const RULE_NAME$44 = "no-clone-element";
1507
+ const RULE_NAME$41 = "no-clone-element";
1006
1508
  var no_clone_element_default = createRule({
1007
1509
  meta: {
1008
1510
  type: "problem",
@@ -1010,11 +1512,11 @@ var no_clone_element_default = createRule({
1010
1512
  messages: { default: "Using 'cloneElement' is uncommon and can lead to fragile code. Use alternatives instead." },
1011
1513
  schema: []
1012
1514
  },
1013
- name: RULE_NAME$44,
1014
- create: create$44,
1515
+ name: RULE_NAME$41,
1516
+ create: create$41,
1015
1517
  defaultOptions: []
1016
1518
  });
1017
- function create$44(context) {
1519
+ function create$41(context) {
1018
1520
  return { CallExpression(node) {
1019
1521
  if (core.isCloneElementCall(context, node)) context.report({
1020
1522
  messageId: "default",
@@ -1025,7 +1527,7 @@ function create$44(context) {
1025
1527
 
1026
1528
  //#endregion
1027
1529
  //#region src/rules/no-component-will-mount.ts
1028
- const RULE_NAME$43 = "no-component-will-mount";
1530
+ const RULE_NAME$40 = "no-component-will-mount";
1029
1531
  var no_component_will_mount_default = createRule({
1030
1532
  meta: {
1031
1533
  type: "problem",
@@ -1034,11 +1536,11 @@ var no_component_will_mount_default = createRule({
1034
1536
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillMount' instead." },
1035
1537
  schema: []
1036
1538
  },
1037
- name: RULE_NAME$43,
1038
- create: create$43,
1539
+ name: RULE_NAME$40,
1540
+ create: create$40,
1039
1541
  defaultOptions: []
1040
1542
  });
1041
- function create$43(context) {
1543
+ function create$40(context) {
1042
1544
  if (!context.sourceCode.text.includes("componentWillMount")) return {};
1043
1545
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
1044
1546
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1058,7 +1560,7 @@ function create$43(context) {
1058
1560
 
1059
1561
  //#endregion
1060
1562
  //#region src/rules/no-component-will-receive-props.ts
1061
- const RULE_NAME$42 = "no-component-will-receive-props";
1563
+ const RULE_NAME$39 = "no-component-will-receive-props";
1062
1564
  var no_component_will_receive_props_default = createRule({
1063
1565
  meta: {
1064
1566
  type: "problem",
@@ -1067,11 +1569,11 @@ var no_component_will_receive_props_default = createRule({
1067
1569
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillReceiveProps' instead." },
1068
1570
  schema: []
1069
1571
  },
1070
- name: RULE_NAME$42,
1071
- create: create$42,
1572
+ name: RULE_NAME$39,
1573
+ create: create$39,
1072
1574
  defaultOptions: []
1073
1575
  });
1074
- function create$42(context) {
1576
+ function create$39(context) {
1075
1577
  if (!context.sourceCode.text.includes("componentWillReceiveProps")) return {};
1076
1578
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
1077
1579
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1091,7 +1593,7 @@ function create$42(context) {
1091
1593
 
1092
1594
  //#endregion
1093
1595
  //#region src/rules/no-component-will-update.ts
1094
- const RULE_NAME$41 = "no-component-will-update";
1596
+ const RULE_NAME$38 = "no-component-will-update";
1095
1597
  var no_component_will_update_default = createRule({
1096
1598
  meta: {
1097
1599
  type: "problem",
@@ -1100,11 +1602,11 @@ var no_component_will_update_default = createRule({
1100
1602
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillUpdate' instead." },
1101
1603
  schema: []
1102
1604
  },
1103
- name: RULE_NAME$41,
1104
- create: create$41,
1605
+ name: RULE_NAME$38,
1606
+ create: create$38,
1105
1607
  defaultOptions: []
1106
1608
  });
1107
- function create$41(context) {
1609
+ function create$38(context) {
1108
1610
  if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
1109
1611
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
1110
1612
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1124,7 +1626,7 @@ function create$41(context) {
1124
1626
 
1125
1627
  //#endregion
1126
1628
  //#region src/rules/no-context-provider.ts
1127
- const RULE_NAME$40 = "no-context-provider";
1629
+ const RULE_NAME$37 = "no-context-provider";
1128
1630
  var no_context_provider_default = createRule({
1129
1631
  meta: {
1130
1632
  type: "problem",
@@ -1133,11 +1635,11 @@ var no_context_provider_default = createRule({
1133
1635
  messages: { default: "In React 19, you can render '<Context>' as a provider instead of '<Context.Provider>'." },
1134
1636
  schema: []
1135
1637
  },
1136
- name: RULE_NAME$40,
1137
- create: create$40,
1638
+ name: RULE_NAME$37,
1639
+ create: create$37,
1138
1640
  defaultOptions: []
1139
1641
  });
1140
- function create$40(context) {
1642
+ function create$37(context) {
1141
1643
  if (!context.sourceCode.text.includes("Provider")) return {};
1142
1644
  const { version } = getSettingsFromContext(context);
1143
1645
  if (compare(version, "19.0.0", "<")) return {};
@@ -1164,7 +1666,7 @@ function create$40(context) {
1164
1666
 
1165
1667
  //#endregion
1166
1668
  //#region src/rules/no-create-ref.ts
1167
- const RULE_NAME$39 = "no-create-ref";
1669
+ const RULE_NAME$36 = "no-create-ref";
1168
1670
  var no_create_ref_default = createRule({
1169
1671
  meta: {
1170
1672
  type: "problem",
@@ -1172,11 +1674,11 @@ var no_create_ref_default = createRule({
1172
1674
  messages: { default: "[Deprecated] Use 'useRef' instead." },
1173
1675
  schema: []
1174
1676
  },
1175
- name: RULE_NAME$39,
1176
- create: create$39,
1677
+ name: RULE_NAME$36,
1678
+ create: create$36,
1177
1679
  defaultOptions: []
1178
1680
  });
1179
- function create$39(context) {
1681
+ function create$36(context) {
1180
1682
  return { CallExpression(node) {
1181
1683
  if (core.isCreateRefCall(context, node) && ast.findParentNode(node, core.isClassComponent) == null) context.report({
1182
1684
  messageId: "default",
@@ -1187,7 +1689,7 @@ function create$39(context) {
1187
1689
 
1188
1690
  //#endregion
1189
1691
  //#region src/rules/no-direct-mutation-state.ts
1190
- const RULE_NAME$38 = "no-direct-mutation-state";
1692
+ const RULE_NAME$35 = "no-direct-mutation-state";
1191
1693
  function isConstructorFunction(node) {
1192
1694
  return ast.isOneOf([AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression])(node) && ast.isMethodOrProperty(node.parent) && node.parent.key.type === AST_NODE_TYPES.Identifier && node.parent.key.name === "constructor";
1193
1695
  }
@@ -1198,11 +1700,11 @@ var no_direct_mutation_state_default = createRule({
1198
1700
  messages: { default: "Do not mutate state directly. Use 'setState()' instead." },
1199
1701
  schema: []
1200
1702
  },
1201
- name: RULE_NAME$38,
1202
- create: create$38,
1703
+ name: RULE_NAME$35,
1704
+ create: create$35,
1203
1705
  defaultOptions: []
1204
1706
  });
1205
- function create$38(context) {
1707
+ function create$35(context) {
1206
1708
  return { AssignmentExpression(node) {
1207
1709
  if (!core.isAssignmentToThisState(node)) return;
1208
1710
  const parentClass = ast.findParentNode(node, ast.isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]));
@@ -1216,7 +1718,7 @@ function create$38(context) {
1216
1718
 
1217
1719
  //#endregion
1218
1720
  //#region src/rules/no-duplicate-key.ts
1219
- const RULE_NAME$37 = "no-duplicate-key";
1721
+ const RULE_NAME$34 = "no-duplicate-key";
1220
1722
  var no_duplicate_key_default = createRule({
1221
1723
  meta: {
1222
1724
  type: "problem",
@@ -1224,11 +1726,11 @@ var no_duplicate_key_default = createRule({
1224
1726
  messages: { default: "The 'key' prop must be unique to its sibling elements." },
1225
1727
  schema: []
1226
1728
  },
1227
- name: RULE_NAME$37,
1228
- create: create$37,
1729
+ name: RULE_NAME$34,
1730
+ create: create$34,
1229
1731
  defaultOptions: []
1230
1732
  });
1231
- function create$37(context) {
1733
+ function create$34(context) {
1232
1734
  if (!context.sourceCode.text.includes("key=")) return {};
1233
1735
  const keyedEntries = /* @__PURE__ */ new Map();
1234
1736
  function isKeyValueEqual(a, b) {
@@ -1283,7 +1785,7 @@ function create$37(context) {
1283
1785
 
1284
1786
  //#endregion
1285
1787
  //#region src/rules/no-forward-ref.ts
1286
- const RULE_NAME$36 = "no-forward-ref";
1788
+ const RULE_NAME$33 = "no-forward-ref";
1287
1789
  var no_forward_ref_default = createRule({
1288
1790
  meta: {
1289
1791
  type: "problem",
@@ -1292,11 +1794,11 @@ var no_forward_ref_default = createRule({
1292
1794
  messages: { default: "In React 19, 'forwardRef' is no longer necessary. Pass 'ref' as a prop instead." },
1293
1795
  schema: []
1294
1796
  },
1295
- name: RULE_NAME$36,
1296
- create: create$36,
1797
+ name: RULE_NAME$33,
1798
+ create: create$33,
1297
1799
  defaultOptions: []
1298
1800
  });
1299
- function create$36(context) {
1801
+ function create$33(context) {
1300
1802
  if (!context.sourceCode.text.includes("forwardRef")) return {};
1301
1803
  const { version } = getSettingsFromContext(context);
1302
1804
  if (compare(version, "19.0.0", "<")) return {};
@@ -1391,7 +1893,7 @@ function getComponentPropsFixes(context, fixer, node, typeArguments) {
1391
1893
 
1392
1894
  //#endregion
1393
1895
  //#region src/rules/no-implicit-key.ts
1394
- const RULE_NAME$35 = "no-implicit-key";
1896
+ const RULE_NAME$32 = "no-implicit-key";
1395
1897
  var no_implicit_key_default = createRule({
1396
1898
  meta: {
1397
1899
  type: "problem",
@@ -1399,11 +1901,11 @@ var no_implicit_key_default = createRule({
1399
1901
  messages: { default: "This spread attribute implicitly passes the 'key' prop to a component, this could lead to unexpected behavior. If you intend to pass the 'key' prop, use 'key={value}'." },
1400
1902
  schema: []
1401
1903
  },
1402
- name: RULE_NAME$35,
1403
- create: create$35,
1904
+ name: RULE_NAME$32,
1905
+ create: create$32,
1404
1906
  defaultOptions: []
1405
1907
  });
1406
- function create$35(context) {
1908
+ function create$32(context) {
1407
1909
  const services = ESLintUtils.getParserServices(context, false);
1408
1910
  const checker = services.program.getTypeChecker();
1409
1911
  return { JSXSpreadAttribute(node) {
@@ -1421,7 +1923,7 @@ function create$35(context) {
1421
1923
 
1422
1924
  //#endregion
1423
1925
  //#region src/rules/no-leaked-conditional-rendering.ts
1424
- const RULE_NAME$34 = "no-leaked-conditional-rendering";
1926
+ const RULE_NAME$31 = "no-leaked-conditional-rendering";
1425
1927
  var no_leaked_conditional_rendering_default = createRule({
1426
1928
  meta: {
1427
1929
  type: "problem",
@@ -1429,11 +1931,11 @@ var no_leaked_conditional_rendering_default = createRule({
1429
1931
  messages: { default: "Potential leaked value {{value}} that might cause unintentionally rendered values or rendering crashes." },
1430
1932
  schema: []
1431
1933
  },
1432
- name: RULE_NAME$34,
1433
- create: create$34,
1934
+ name: RULE_NAME$31,
1935
+ create: create$31,
1434
1936
  defaultOptions: []
1435
1937
  });
1436
- function create$34(context) {
1938
+ function create$31(context) {
1437
1939
  if (!context.sourceCode.text.includes("&&")) return {};
1438
1940
  const { version } = getSettingsFromContext(context);
1439
1941
  const allowedVariants = [
@@ -1490,7 +1992,7 @@ function create$34(context) {
1490
1992
 
1491
1993
  //#endregion
1492
1994
  //#region src/rules/no-missing-component-display-name.ts
1493
- const RULE_NAME$33 = "no-missing-component-display-name";
1995
+ const RULE_NAME$30 = "no-missing-component-display-name";
1494
1996
  var no_missing_component_display_name_default = createRule({
1495
1997
  meta: {
1496
1998
  type: "problem",
@@ -1498,11 +2000,11 @@ var no_missing_component_display_name_default = createRule({
1498
2000
  messages: { default: "Add missing 'displayName' for component." },
1499
2001
  schema: []
1500
2002
  },
1501
- name: RULE_NAME$33,
1502
- create: create$33,
2003
+ name: RULE_NAME$30,
2004
+ create: create$30,
1503
2005
  defaultOptions: []
1504
2006
  });
1505
- function create$33(context) {
2007
+ function create$30(context) {
1506
2008
  if (!context.sourceCode.text.includes("memo") && !context.sourceCode.text.includes("forwardRef")) return {};
1507
2009
  const { ctx, visitor } = core.useComponentCollector(context, {
1508
2010
  collectDisplayName: true,
@@ -1524,7 +2026,7 @@ function create$33(context) {
1524
2026
 
1525
2027
  //#endregion
1526
2028
  //#region src/rules/no-missing-context-display-name.ts
1527
- const RULE_NAME$32 = "no-missing-context-display-name";
2029
+ const RULE_NAME$29 = "no-missing-context-display-name";
1528
2030
  var no_missing_context_display_name_default = createRule({
1529
2031
  meta: {
1530
2032
  type: "problem",
@@ -1533,11 +2035,11 @@ var no_missing_context_display_name_default = createRule({
1533
2035
  messages: { default: "Add missing 'displayName' for context." },
1534
2036
  schema: []
1535
2037
  },
1536
- name: RULE_NAME$32,
1537
- create: create$32,
2038
+ name: RULE_NAME$29,
2039
+ create: create$29,
1538
2040
  defaultOptions: []
1539
2041
  });
1540
- function create$32(context) {
2042
+ function create$29(context) {
1541
2043
  if (!context.sourceCode.text.includes("createContext")) return {};
1542
2044
  const createCalls = [];
1543
2045
  const displayNameAssignments = [];
@@ -1589,7 +2091,7 @@ function create$32(context) {
1589
2091
 
1590
2092
  //#endregion
1591
2093
  //#region src/rules/no-missing-key.ts
1592
- const RULE_NAME$31 = "no-missing-key";
2094
+ const RULE_NAME$28 = "no-missing-key";
1593
2095
  var no_missing_key_default = createRule({
1594
2096
  meta: {
1595
2097
  type: "problem",
@@ -1600,11 +2102,11 @@ var no_missing_key_default = createRule({
1600
2102
  },
1601
2103
  schema: []
1602
2104
  },
1603
- name: RULE_NAME$31,
1604
- create: create$31,
2105
+ name: RULE_NAME$28,
2106
+ create: create$28,
1605
2107
  defaultOptions: []
1606
2108
  });
1607
- function create$31(ctx) {
2109
+ function create$28(ctx) {
1608
2110
  let inChildrenToArray = false;
1609
2111
  function check(node) {
1610
2112
  if (node.type === AST_NODE_TYPES.JSXElement) return core.getJsxAttribute(ctx, node)("key") == null ? {
@@ -1668,7 +2170,7 @@ function create$31(ctx) {
1668
2170
 
1669
2171
  //#endregion
1670
2172
  //#region src/rules/no-misused-capture-owner-stack.ts
1671
- const RULE_NAME$30 = "no-misused-capture-owner-stack";
2173
+ const RULE_NAME$27 = "no-misused-capture-owner-stack";
1672
2174
  var no_misused_capture_owner_stack_default = createRule({
1673
2175
  meta: {
1674
2176
  type: "problem",
@@ -1679,11 +2181,11 @@ var no_misused_capture_owner_stack_default = createRule({
1679
2181
  },
1680
2182
  schema: []
1681
2183
  },
1682
- name: RULE_NAME$30,
1683
- create: create$30,
2184
+ name: RULE_NAME$27,
2185
+ create: create$27,
1684
2186
  defaultOptions: []
1685
2187
  });
1686
- function create$30(context) {
2188
+ function create$27(context) {
1687
2189
  if (!context.sourceCode.text.includes("captureOwnerStack")) return {};
1688
2190
  const { importSource } = getSettingsFromContext(context);
1689
2191
  return {
@@ -1714,7 +2216,7 @@ function isDevelopmentOnlyCheck(node) {
1714
2216
 
1715
2217
  //#endregion
1716
2218
  //#region src/rules/no-nested-component-definitions.ts
1717
- const RULE_NAME$29 = "no-nested-component-definitions";
2219
+ const RULE_NAME$26 = "no-nested-component-definitions";
1718
2220
  var no_nested_component_definitions_default = createRule({
1719
2221
  meta: {
1720
2222
  type: "problem",
@@ -1722,11 +2224,11 @@ var no_nested_component_definitions_default = createRule({
1722
2224
  messages: { default: "Do not nest component definitions inside other components or props. {{suggestion}}" },
1723
2225
  schema: []
1724
2226
  },
1725
- name: RULE_NAME$29,
1726
- create: create$29,
2227
+ name: RULE_NAME$26,
2228
+ create: create$26,
1727
2229
  defaultOptions: []
1728
2230
  });
1729
- function create$29(context) {
2231
+ function create$26(context) {
1730
2232
  const hint = core.ComponentDetectionHint.DoNotIncludeJsxWithNumberValue | core.ComponentDetectionHint.DoNotIncludeJsxWithBooleanValue | core.ComponentDetectionHint.DoNotIncludeJsxWithNullValue | core.ComponentDetectionHint.DoNotIncludeJsxWithStringValue | core.ComponentDetectionHint.DoNotIncludeJsxWithUndefinedValue | core.ComponentDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx | core.ComponentDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayPattern | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedInArrayExpression | core.ComponentDetectionHint.DoNotIncludeFunctionDefinedAsArrayMapCallback;
1731
2233
  const fCollector = core.useComponentCollector(context, { hint });
1732
2234
  const cCollector = core.useComponentCollectorLegacy(context);
@@ -1831,7 +2333,7 @@ function isInsideCreateElementProps(context, node) {
1831
2333
 
1832
2334
  //#endregion
1833
2335
  //#region src/rules/no-nested-lazy-component-declarations.ts
1834
- const RULE_NAME$28 = "no-nested-lazy-component-declarations";
2336
+ const RULE_NAME$25 = "no-nested-lazy-component-declarations";
1835
2337
  var no_nested_lazy_component_declarations_default = createRule({
1836
2338
  meta: {
1837
2339
  type: "problem",
@@ -1839,11 +2341,11 @@ var no_nested_lazy_component_declarations_default = createRule({
1839
2341
  messages: { default: "Do not declare lazy components inside other components. Instead, always declare them at the top level of your module." },
1840
2342
  schema: []
1841
2343
  },
1842
- name: RULE_NAME$28,
1843
- create: create$28,
2344
+ name: RULE_NAME$25,
2345
+ create: create$25,
1844
2346
  defaultOptions: []
1845
2347
  });
1846
- function create$28(context) {
2348
+ function create$25(context) {
1847
2349
  const hint = core.ComponentDetectionHint.None;
1848
2350
  const collector = core.useComponentCollector(context, { hint });
1849
2351
  const collectorLegacy = core.useComponentCollectorLegacy(context);
@@ -1872,7 +2374,7 @@ function create$28(context) {
1872
2374
 
1873
2375
  //#endregion
1874
2376
  //#region src/rules/no-redundant-should-component-update.ts
1875
- const RULE_NAME$27 = "no-redundant-should-component-update";
2377
+ const RULE_NAME$24 = "no-redundant-should-component-update";
1876
2378
  function isShouldComponentUpdate(node) {
1877
2379
  return ast.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "shouldComponentUpdate";
1878
2380
  }
@@ -1883,11 +2385,11 @@ var no_redundant_should_component_update_default = createRule({
1883
2385
  messages: { default: "'{{componentName}}' does not need 'shouldComponentUpdate' when extending 'React.PureComponent'." },
1884
2386
  schema: []
1885
2387
  },
1886
- name: RULE_NAME$27,
1887
- create: create$27,
2388
+ name: RULE_NAME$24,
2389
+ create: create$24,
1888
2390
  defaultOptions: []
1889
2391
  });
1890
- function create$27(context) {
2392
+ function create$24(context) {
1891
2393
  if (!context.sourceCode.text.includes("shouldComponentUpdate")) return {};
1892
2394
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
1893
2395
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1905,7 +2407,7 @@ function create$27(context) {
1905
2407
 
1906
2408
  //#endregion
1907
2409
  //#region src/rules/no-set-state-in-component-did-mount.ts
1908
- const RULE_NAME$26 = "no-set-state-in-component-did-mount";
2410
+ const RULE_NAME$23 = "no-set-state-in-component-did-mount";
1909
2411
  var no_set_state_in_component_did_mount_default = createRule({
1910
2412
  meta: {
1911
2413
  type: "problem",
@@ -1913,11 +2415,11 @@ var no_set_state_in_component_did_mount_default = createRule({
1913
2415
  messages: { default: "Do not call `this.setState` in `componentDidMount` outside functions such as callbacks." },
1914
2416
  schema: []
1915
2417
  },
1916
- name: RULE_NAME$26,
1917
- create: create$26,
2418
+ name: RULE_NAME$23,
2419
+ create: create$23,
1918
2420
  defaultOptions: []
1919
2421
  });
1920
- function create$26(context) {
2422
+ function create$23(context) {
1921
2423
  if (!context.sourceCode.text.includes("componentDidMount")) return {};
1922
2424
  return { CallExpression(node) {
1923
2425
  if (!core.isThisSetState(node)) return;
@@ -1935,7 +2437,7 @@ function create$26(context) {
1935
2437
 
1936
2438
  //#endregion
1937
2439
  //#region src/rules/no-set-state-in-component-did-update.ts
1938
- const RULE_NAME$25 = "no-set-state-in-component-did-update";
2440
+ const RULE_NAME$22 = "no-set-state-in-component-did-update";
1939
2441
  var no_set_state_in_component_did_update_default = createRule({
1940
2442
  meta: {
1941
2443
  type: "problem",
@@ -1943,11 +2445,11 @@ var no_set_state_in_component_did_update_default = createRule({
1943
2445
  messages: { default: "Do not call `this.setState` in `componentDidUpdate` outside functions such as callbacks." },
1944
2446
  schema: []
1945
2447
  },
1946
- name: RULE_NAME$25,
1947
- create: create$25,
2448
+ name: RULE_NAME$22,
2449
+ create: create$22,
1948
2450
  defaultOptions: []
1949
2451
  });
1950
- function create$25(context) {
2452
+ function create$22(context) {
1951
2453
  if (!context.sourceCode.text.includes("componentDidUpdate")) return {};
1952
2454
  return { CallExpression(node) {
1953
2455
  if (!core.isThisSetState(node)) return;
@@ -1965,7 +2467,7 @@ function create$25(context) {
1965
2467
 
1966
2468
  //#endregion
1967
2469
  //#region src/rules/no-set-state-in-component-will-update.ts
1968
- const RULE_NAME$24 = "no-set-state-in-component-will-update";
2470
+ const RULE_NAME$21 = "no-set-state-in-component-will-update";
1969
2471
  var no_set_state_in_component_will_update_default = createRule({
1970
2472
  meta: {
1971
2473
  type: "problem",
@@ -1973,11 +2475,11 @@ var no_set_state_in_component_will_update_default = createRule({
1973
2475
  messages: { default: "Do not call `this.setState` in `componentWillUpdate` outside functions such as callbacks." },
1974
2476
  schema: []
1975
2477
  },
1976
- name: RULE_NAME$24,
1977
- create: create$24,
2478
+ name: RULE_NAME$21,
2479
+ create: create$21,
1978
2480
  defaultOptions: []
1979
2481
  });
1980
- function create$24(context) {
2482
+ function create$21(context) {
1981
2483
  if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
1982
2484
  return { CallExpression(node) {
1983
2485
  if (!core.isThisSetState(node)) return;
@@ -1993,70 +2495,9 @@ function create$24(context) {
1993
2495
  } };
1994
2496
  }
1995
2497
 
1996
- //#endregion
1997
- //#region src/rules/no-unnecessary-key.ts
1998
- const RULE_NAME$23 = "no-unnecessary-key";
1999
- var no_unnecessary_key_default = createRule({
2000
- meta: {
2001
- type: "problem",
2002
- docs: { description: "Disallows unnecessary 'key' props on nested child elements when rendering lists." },
2003
- messages: { default: "Unnecessary `key` prop on this element. {{reason}}" },
2004
- schema: []
2005
- },
2006
- name: RULE_NAME$23,
2007
- create: create$23,
2008
- defaultOptions: []
2009
- });
2010
- function create$23(context) {
2011
- if (!context.sourceCode.text.includes("key=")) return {};
2012
- const jsxConfig = {
2013
- ...core.getJsxConfigFromContext(context),
2014
- ...core.getJsxConfigFromAnnotation(context)
2015
- };
2016
- return { JSXAttribute(node) {
2017
- if (node.name.name !== "key") return;
2018
- const jsxElement = node.parent.parent;
2019
- if (core.isJsxFragmentElement(context, jsxElement, jsxConfig)) return;
2020
- if (jsxElement.openingElement.attributes.some((attr) => attr.type === AST_NODE_TYPES.JSXSpreadAttribute)) return;
2021
- if (ast.findParentNode(jsxElement, (n) => core.isRenderFunctionLoose(context, n)) != null) return;
2022
- const mapCallback = ast.findParentNode(jsxElement, isArrayMethodCallback);
2023
- if (mapCallback == null || ast.findParentNode(jsxElement, ast.isFunction) !== mapCallback) return;
2024
- if (context.sourceCode.getScope(mapCallback) !== context.sourceCode.getScope(jsxElement)) return;
2025
- const keyedElementOrElse = ast.findParentNode(jsxElement, (n) => {
2026
- if (n === mapCallback) return true;
2027
- return ast.isJSXElement(n) && core.getJsxAttribute(context, n)("key") != null;
2028
- });
2029
- if (keyedElementOrElse == null || keyedElementOrElse === mapCallback) return;
2030
- context.report({
2031
- messageId: "default",
2032
- node,
2033
- data: { reason: "A parent element already has a `key` prop in the same list rendering context." }
2034
- });
2035
- } };
2036
- }
2037
- function getArrayMethodCallbackPosition(methodName) {
2038
- switch (methodName) {
2039
- case "filter":
2040
- case "flatMap":
2041
- case "forEach":
2042
- case "map":
2043
- case "reduce":
2044
- case "reduceRight": return 0;
2045
- case "from":
2046
- case "fromAsync": return 1;
2047
- default: return -1;
2048
- }
2049
- }
2050
- function isArrayMethodCallback(node) {
2051
- const parent = node.parent;
2052
- if (parent?.type !== AST_NODE_TYPES.CallExpression) return false;
2053
- if (parent.callee.type !== AST_NODE_TYPES.MemberExpression || parent.callee.property.type !== AST_NODE_TYPES.Identifier) return false;
2054
- return parent.arguments[getArrayMethodCallbackPosition(parent.callee.property.name)] === node;
2055
- }
2056
-
2057
2498
  //#endregion
2058
2499
  //#region src/rules/no-unnecessary-use-callback.ts
2059
- const RULE_NAME$22 = "no-unnecessary-use-callback";
2500
+ const RULE_NAME$20 = "no-unnecessary-use-callback";
2060
2501
  var no_unnecessary_use_callback_default = createRule({
2061
2502
  meta: {
2062
2503
  type: "problem",
@@ -2067,11 +2508,11 @@ var no_unnecessary_use_callback_default = createRule({
2067
2508
  },
2068
2509
  schema: []
2069
2510
  },
2070
- name: RULE_NAME$22,
2071
- create: create$22,
2511
+ name: RULE_NAME$20,
2512
+ create: create$20,
2072
2513
  defaultOptions: []
2073
2514
  });
2074
- function create$22(context) {
2515
+ function create$20(context) {
2075
2516
  if (!context.sourceCode.text.includes("useCallback")) return {};
2076
2517
  return { VariableDeclarator(node) {
2077
2518
  const { id, init } = node;
@@ -2133,7 +2574,7 @@ function checkForUsageInsideUseEffect$1(sourceCode, node) {
2133
2574
 
2134
2575
  //#endregion
2135
2576
  //#region src/rules/no-unnecessary-use-memo.ts
2136
- const RULE_NAME$21 = "no-unnecessary-use-memo";
2577
+ const RULE_NAME$19 = "no-unnecessary-use-memo";
2137
2578
  var no_unnecessary_use_memo_default = createRule({
2138
2579
  meta: {
2139
2580
  type: "problem",
@@ -2144,11 +2585,11 @@ var no_unnecessary_use_memo_default = createRule({
2144
2585
  },
2145
2586
  schema: []
2146
2587
  },
2147
- name: RULE_NAME$21,
2148
- create: create$21,
2588
+ name: RULE_NAME$19,
2589
+ create: create$19,
2149
2590
  defaultOptions: []
2150
2591
  });
2151
- function create$21(context) {
2592
+ function create$19(context) {
2152
2593
  if (!context.sourceCode.text.includes("useMemo")) return {};
2153
2594
  return { VariableDeclarator(node) {
2154
2595
  const { id, init } = node;
@@ -2214,7 +2655,7 @@ function checkForUsageInsideUseEffect(sourceCode, node) {
2214
2655
 
2215
2656
  //#endregion
2216
2657
  //#region src/rules/no-unnecessary-use-prefix.ts
2217
- const RULE_NAME$20 = "no-unnecessary-use-prefix";
2658
+ const RULE_NAME$18 = "no-unnecessary-use-prefix";
2218
2659
  const WELL_KNOWN_HOOKS = ["useMDXComponents"];
2219
2660
  function containsUseComments(context, node) {
2220
2661
  return context.sourceCode.getCommentsInside(node).some(({ value }) => /use\([\s\S]*?\)/u.test(value) || /use[A-Z0-9]\w*\([\s\S]*?\)/u.test(value));
@@ -2226,11 +2667,11 @@ var no_unnecessary_use_prefix_default = createRule({
2226
2667
  messages: { default: "If your function doesn't call any Hooks, avoid the 'use' prefix. Instead, write it as a regular function without the 'use' prefix." },
2227
2668
  schema: []
2228
2669
  },
2229
- name: RULE_NAME$20,
2230
- create: create$20,
2670
+ name: RULE_NAME$18,
2671
+ create: create$18,
2231
2672
  defaultOptions: []
2232
2673
  });
2233
- function create$20(context) {
2674
+ function create$18(context) {
2234
2675
  const { ctx, visitor } = core.useHookCollector(context);
2235
2676
  return defineRuleListener(visitor, { "Program:exit"(program) {
2236
2677
  for (const { id, name, node, hookCalls } of ctx.getAllHooks(program)) {
@@ -2250,7 +2691,7 @@ function create$20(context) {
2250
2691
 
2251
2692
  //#endregion
2252
2693
  //#region src/rules/no-unsafe-component-will-mount.ts
2253
- const RULE_NAME$19 = "no-unsafe-component-will-mount";
2694
+ const RULE_NAME$17 = "no-unsafe-component-will-mount";
2254
2695
  var no_unsafe_component_will_mount_default = createRule({
2255
2696
  meta: {
2256
2697
  type: "problem",
@@ -2258,11 +2699,11 @@ var no_unsafe_component_will_mount_default = createRule({
2258
2699
  messages: { default: "Do not use 'UNSAFE_componentWillMount'." },
2259
2700
  schema: []
2260
2701
  },
2261
- name: RULE_NAME$19,
2262
- create: create$19,
2702
+ name: RULE_NAME$17,
2703
+ create: create$17,
2263
2704
  defaultOptions: []
2264
2705
  });
2265
- function create$19(context) {
2706
+ function create$17(context) {
2266
2707
  if (!context.sourceCode.text.includes("UNSAFE_componentWillMount")) return {};
2267
2708
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
2268
2709
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -2278,7 +2719,7 @@ function create$19(context) {
2278
2719
 
2279
2720
  //#endregion
2280
2721
  //#region src/rules/no-unsafe-component-will-receive-props.ts
2281
- const RULE_NAME$18 = "no-unsafe-component-will-receive-props";
2722
+ const RULE_NAME$16 = "no-unsafe-component-will-receive-props";
2282
2723
  var no_unsafe_component_will_receive_props_default = createRule({
2283
2724
  meta: {
2284
2725
  type: "problem",
@@ -2286,11 +2727,11 @@ var no_unsafe_component_will_receive_props_default = createRule({
2286
2727
  messages: { default: "Do not use 'UNSAFE_componentWillReceiveProps'." },
2287
2728
  schema: []
2288
2729
  },
2289
- name: RULE_NAME$18,
2290
- create: create$18,
2730
+ name: RULE_NAME$16,
2731
+ create: create$16,
2291
2732
  defaultOptions: []
2292
2733
  });
2293
- function create$18(context) {
2734
+ function create$16(context) {
2294
2735
  if (!context.sourceCode.text.includes("UNSAFE_componentWillReceiveProps")) return {};
2295
2736
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
2296
2737
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -2306,7 +2747,7 @@ function create$18(context) {
2306
2747
 
2307
2748
  //#endregion
2308
2749
  //#region src/rules/no-unsafe-component-will-update.ts
2309
- const RULE_NAME$17 = "no-unsafe-component-will-update";
2750
+ const RULE_NAME$15 = "no-unsafe-component-will-update";
2310
2751
  var no_unsafe_component_will_update_default = createRule({
2311
2752
  meta: {
2312
2753
  type: "problem",
@@ -2314,11 +2755,11 @@ var no_unsafe_component_will_update_default = createRule({
2314
2755
  messages: { default: "Do not use 'UNSAFE_componentWillUpdate'." },
2315
2756
  schema: []
2316
2757
  },
2317
- name: RULE_NAME$17,
2318
- create: create$17,
2758
+ name: RULE_NAME$15,
2759
+ create: create$15,
2319
2760
  defaultOptions: []
2320
2761
  });
2321
- function create$17(context) {
2762
+ function create$15(context) {
2322
2763
  if (!context.sourceCode.text.includes("UNSAFE_componentWillUpdate")) return {};
2323
2764
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
2324
2765
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -2334,7 +2775,7 @@ function create$17(context) {
2334
2775
 
2335
2776
  //#endregion
2336
2777
  //#region src/rules/no-unstable-context-value.ts
2337
- const RULE_NAME$16 = "no-unstable-context-value";
2778
+ const RULE_NAME$14 = "no-unstable-context-value";
2338
2779
  var no_unstable_context_value_default = createRule({
2339
2780
  meta: {
2340
2781
  type: "problem",
@@ -2342,13 +2783,13 @@ var no_unstable_context_value_default = createRule({
2342
2783
  messages: { unstableContextValue: "A/an '{{kind}}' passed as the value prop to the context provider should not be constructed. It will change on every render. {{suggestion}}" },
2343
2784
  schema: []
2344
2785
  },
2345
- name: RULE_NAME$16,
2346
- create: create$16,
2786
+ name: RULE_NAME$14,
2787
+ create: create$14,
2347
2788
  defaultOptions: []
2348
2789
  });
2349
- function create$16(context) {
2350
- if (ast.getFileDirectives(context.sourceCode.ast).some((d) => d.directive === "use memo")) return {};
2351
- const { version } = getSettingsFromContext(context);
2790
+ function create$14(context) {
2791
+ const { isCompilerEnabled, version } = getSettingsFromContext(context);
2792
+ if (isCompilerEnabled && ast.isDirectiveInFile(context.sourceCode.ast, "use memo")) return {};
2352
2793
  const isReact18OrBelow = compare(version, "19.0.0", "<");
2353
2794
  const { ctx, visitor } = core.useComponentCollector(context);
2354
2795
  const constructions = /* @__PURE__ */ new WeakMap();
@@ -2359,6 +2800,7 @@ function create$16(context) {
2359
2800
  if (!isContextName(selfName, isReact18OrBelow)) return;
2360
2801
  const functionEntry = ctx.getCurrentEntry();
2361
2802
  if (functionEntry == null) return;
2803
+ if (isCompilerEnabled && ast.isDirectiveInFunction(functionEntry.node, "use memo")) return;
2362
2804
  const attribute = node.attributes.find((attribute) => attribute.type === AST_NODE_TYPES.JSXAttribute && attribute.name.name === "value");
2363
2805
  if (attribute == null || !("value" in attribute)) return;
2364
2806
  const value = attribute.value;
@@ -2394,8 +2836,8 @@ function isContextName(name, isReact18OrBelow) {
2394
2836
 
2395
2837
  //#endregion
2396
2838
  //#region src/rules/no-unstable-default-props.ts
2397
- const RULE_NAME$15 = "no-unstable-default-props";
2398
- const defaultOptions$2 = [{ safeDefaultProps: [] }];
2839
+ const RULE_NAME$13 = "no-unstable-default-props";
2840
+ const defaultOptions$1 = [{ safeDefaultProps: [] }];
2399
2841
  const schema$1 = [{
2400
2842
  type: "object",
2401
2843
  additionalProperties: false,
@@ -2411,9 +2853,9 @@ var no_unstable_default_props_default = createRule({
2411
2853
  messages: { default: "A/an '{{kind}}' as default prop. This could lead to potential infinite render loop in React. Use a variable instead of '{{kind}}'." },
2412
2854
  schema: schema$1
2413
2855
  },
2414
- name: RULE_NAME$15,
2415
- create: create$15,
2416
- defaultOptions: defaultOptions$2
2856
+ name: RULE_NAME$13,
2857
+ create: create$13,
2858
+ defaultOptions: defaultOptions$1
2417
2859
  });
2418
2860
  function extractIdentifier(node) {
2419
2861
  if (node.type === AST_NODE_TYPES.NewExpression && node.callee.type === AST_NODE_TYPES.Identifier) return node.callee.name;
@@ -2423,8 +2865,9 @@ function extractIdentifier(node) {
2423
2865
  }
2424
2866
  return null;
2425
2867
  }
2426
- function create$15(context, [options]) {
2427
- if (ast.getFileDirectives(context.sourceCode.ast).some((d) => d.directive === "use memo")) return {};
2868
+ function create$13(context, [options]) {
2869
+ const { isCompilerEnabled } = getSettingsFromContext(context);
2870
+ if (isCompilerEnabled && ast.isDirectiveInFile(context.sourceCode.ast, "use memo")) return {};
2428
2871
  const { ctx, visitor } = core.useComponentCollector(context);
2429
2872
  const declarators = /* @__PURE__ */ new WeakMap();
2430
2873
  const { safeDefaultProps = [] } = options;
@@ -2467,7 +2910,7 @@ function create$15(context, [options]) {
2467
2910
 
2468
2911
  //#endregion
2469
2912
  //#region src/rules/no-unused-class-component-members.ts
2470
- const RULE_NAME$14 = "no-unused-class-component-members";
2913
+ const RULE_NAME$12 = "no-unused-class-component-members";
2471
2914
  const LIFECYCLE_METHODS = new Set([
2472
2915
  "componentDidCatch",
2473
2916
  "componentDidMount",
@@ -2498,11 +2941,11 @@ var no_unused_class_component_members_default = createRule({
2498
2941
  messages: { default: "Unused method or property '{{methodName}}'' of class '{{className}}'." },
2499
2942
  schema: []
2500
2943
  },
2501
- name: RULE_NAME$14,
2502
- create: create$14,
2944
+ name: RULE_NAME$12,
2945
+ create: create$12,
2503
2946
  defaultOptions: []
2504
2947
  });
2505
- function create$14(context) {
2948
+ function create$12(context) {
2506
2949
  const classStack = [];
2507
2950
  const methodStack = [];
2508
2951
  const propertyDefs = /* @__PURE__ */ new WeakMap();
@@ -2583,7 +3026,7 @@ function create$14(context) {
2583
3026
 
2584
3027
  //#endregion
2585
3028
  //#region src/rules/no-unused-props.ts
2586
- const RULE_NAME$13 = "no-unused-props";
3029
+ const RULE_NAME$11 = "no-unused-props";
2587
3030
  var no_unused_props_default = createRule({
2588
3031
  meta: {
2589
3032
  type: "problem",
@@ -2591,11 +3034,11 @@ var no_unused_props_default = createRule({
2591
3034
  messages: { default: "Prop `{{name}}` is declared but never used" },
2592
3035
  schema: []
2593
3036
  },
2594
- name: RULE_NAME$13,
2595
- create: create$13,
3037
+ name: RULE_NAME$11,
3038
+ create: create$11,
2596
3039
  defaultOptions: []
2597
3040
  });
2598
- function create$13(context) {
3041
+ function create$11(context) {
2599
3042
  const services = ESLintUtils.getParserServices(context, false);
2600
3043
  const { ctx, visitor } = core.useComponentCollector(context);
2601
3044
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -2614,7 +3057,7 @@ function create$13(context) {
2614
3057
  if (usedPropKeys.has(declaredProp.name)) totalUsedProps.add(declaredProp);
2615
3058
  }
2616
3059
  }
2617
- const unusedProps = [...totalDeclaredProps].filter((x) => !totalUsedProps.has(x));
3060
+ const unusedProps = totalDeclaredProps.difference(totalUsedProps);
2618
3061
  for (const unusedProp of unusedProps) reportUnusedProp(context, services, unusedProp);
2619
3062
  } });
2620
3063
  }
@@ -2693,7 +3136,7 @@ function reportUnusedProp(context, services, prop) {
2693
3136
 
2694
3137
  //#endregion
2695
3138
  //#region src/rules/no-unused-state.ts
2696
- const RULE_NAME$12 = "no-unused-state";
3139
+ const RULE_NAME$10 = "no-unused-state";
2697
3140
  function isKeyLiteral(node, key) {
2698
3141
  return match(key).with({ type: AST_NODE_TYPES.Literal }, constTrue).with({
2699
3142
  type: AST_NODE_TYPES.TemplateLiteral,
@@ -2707,11 +3150,11 @@ var no_unused_state_default = createRule({
2707
3150
  messages: { default: "Unused class component state in '{{className}}'" },
2708
3151
  schema: []
2709
3152
  },
2710
- name: RULE_NAME$12,
2711
- create: create$12,
3153
+ name: RULE_NAME$10,
3154
+ create: create$10,
2712
3155
  defaultOptions: []
2713
3156
  });
2714
- function create$12(context) {
3157
+ function create$10(context) {
2715
3158
  const classStack = [];
2716
3159
  const methodStack = [];
2717
3160
  const constructorStack = [];
@@ -2820,7 +3263,7 @@ function create$12(context) {
2820
3263
 
2821
3264
  //#endregion
2822
3265
  //#region src/rules/no-use-context.ts
2823
- const RULE_NAME$11 = "no-use-context";
3266
+ const RULE_NAME$9 = "no-use-context";
2824
3267
  var no_use_context_default = createRule({
2825
3268
  meta: {
2826
3269
  type: "problem",
@@ -2829,11 +3272,11 @@ var no_use_context_default = createRule({
2829
3272
  messages: { default: "In React 19, 'use' is preferred over 'useContext' because it is more flexible." },
2830
3273
  schema: []
2831
3274
  },
2832
- name: RULE_NAME$11,
2833
- create: create$11,
3275
+ name: RULE_NAME$9,
3276
+ create: create$9,
2834
3277
  defaultOptions: []
2835
3278
  });
2836
- function create$11(context) {
3279
+ function create$9(context) {
2837
3280
  if (!context.sourceCode.text.includes("useContext")) return {};
2838
3281
  const settings = getSettingsFromContext(context);
2839
3282
  if (compare(settings.version, "19.0.0", "<")) return {};
@@ -2898,7 +3341,7 @@ function getCorrelativeTokens(context, node) {
2898
3341
 
2899
3342
  //#endregion
2900
3343
  //#region src/rules/no-useless-forward-ref.ts
2901
- const RULE_NAME$10 = "no-useless-forward-ref";
3344
+ const RULE_NAME$8 = "no-useless-forward-ref";
2902
3345
  var no_useless_forward_ref_default = createRule({
2903
3346
  meta: {
2904
3347
  type: "problem",
@@ -2906,11 +3349,11 @@ var no_useless_forward_ref_default = createRule({
2906
3349
  messages: { default: "A 'forwardRef' is used with this component but no 'ref' parameter is set." },
2907
3350
  schema: []
2908
3351
  },
2909
- name: RULE_NAME$10,
2910
- create: create$10,
3352
+ name: RULE_NAME$8,
3353
+ create: create$8,
2911
3354
  defaultOptions: []
2912
3355
  });
2913
- function create$10(context) {
3356
+ function create$8(context) {
2914
3357
  return { CallExpression(node) {
2915
3358
  if (!core.isForwardRefCall(context, node)) return;
2916
3359
  const [component] = node.arguments;
@@ -2925,8 +3368,8 @@ function create$10(context) {
2925
3368
 
2926
3369
  //#endregion
2927
3370
  //#region src/rules/no-useless-fragment.ts
2928
- const RULE_NAME$9 = "no-useless-fragment";
2929
- const defaultOptions$1 = [{
3371
+ const RULE_NAME$7 = "no-useless-fragment";
3372
+ const defaultOptions = [{
2930
3373
  allowEmptyFragment: false,
2931
3374
  allowExpressions: true
2932
3375
  }];
@@ -2947,17 +3390,17 @@ const schema = [{
2947
3390
  var no_useless_fragment_default = createRule({
2948
3391
  meta: {
2949
3392
  type: "problem",
2950
- defaultOptions: [...defaultOptions$1],
3393
+ defaultOptions: [...defaultOptions],
2951
3394
  docs: { description: "Disallows useless fragment elements." },
2952
3395
  fixable: "code",
2953
3396
  messages: { default: "A fragment {{reason}} is useless." },
2954
3397
  schema
2955
3398
  },
2956
- name: RULE_NAME$9,
2957
- create: create$9,
2958
- defaultOptions: defaultOptions$1
3399
+ name: RULE_NAME$7,
3400
+ create: create$7,
3401
+ defaultOptions
2959
3402
  });
2960
- function create$9(context, [option]) {
3403
+ function create$7(context, [option]) {
2961
3404
  const { allowEmptyFragment = false, allowExpressions = true } = option;
2962
3405
  const jsxConfig = {
2963
3406
  ...core.getJsxConfigFromContext(context),
@@ -3065,7 +3508,7 @@ function trimLikeReact(text) {
3065
3508
 
3066
3509
  //#endregion
3067
3510
  //#region src/rules/prefer-destructuring-assignment.ts
3068
- const RULE_NAME$8 = "prefer-destructuring-assignment";
3511
+ const RULE_NAME$6 = "prefer-destructuring-assignment";
3069
3512
  var prefer_destructuring_assignment_default = createRule({
3070
3513
  meta: {
3071
3514
  type: "problem",
@@ -3073,11 +3516,11 @@ var prefer_destructuring_assignment_default = createRule({
3073
3516
  messages: { default: "Use destructuring assignment for component props." },
3074
3517
  schema: []
3075
3518
  },
3076
- name: RULE_NAME$8,
3077
- create: create$8,
3519
+ name: RULE_NAME$6,
3520
+ create: create$6,
3078
3521
  defaultOptions: []
3079
3522
  });
3080
- function create$8(context) {
3523
+ function create$6(context) {
3081
3524
  const { ctx, visitor } = core.useComponentCollector(context);
3082
3525
  return defineRuleListener(visitor, { "Program:exit"(program) {
3083
3526
  for (const component of ctx.getAllComponents(program)) {
@@ -3101,7 +3544,7 @@ function create$8(context) {
3101
3544
 
3102
3545
  //#endregion
3103
3546
  //#region src/rules/prefer-namespace-import.ts
3104
- const RULE_NAME$7 = "prefer-namespace-import";
3547
+ const RULE_NAME$5 = "prefer-namespace-import";
3105
3548
  var prefer_namespace_import_default = createRule({
3106
3549
  meta: {
3107
3550
  type: "problem",
@@ -3110,11 +3553,11 @@ var prefer_namespace_import_default = createRule({
3110
3553
  messages: { default: "Prefer importing React as 'import * as React from \"{{importSource}}\"';" },
3111
3554
  schema: []
3112
3555
  },
3113
- name: RULE_NAME$7,
3114
- create: create$7,
3556
+ name: RULE_NAME$5,
3557
+ create: create$5,
3115
3558
  defaultOptions: []
3116
3559
  });
3117
- function create$7(context) {
3560
+ function create$5(context) {
3118
3561
  const { importSource } = getSettingsFromContext(context);
3119
3562
  return { [`ImportDeclaration[source.value="${importSource}"] ImportDefaultSpecifier`](node) {
3120
3563
  const hasOtherSpecifiers = node.parent.specifiers.length > 1;
@@ -3138,7 +3581,7 @@ function create$7(context) {
3138
3581
 
3139
3582
  //#endregion
3140
3583
  //#region src/rules/prefer-read-only-props.ts
3141
- const RULE_NAME$6 = "prefer-read-only-props";
3584
+ const RULE_NAME$4 = "prefer-read-only-props";
3142
3585
  var prefer_read_only_props_default = createRule({
3143
3586
  meta: {
3144
3587
  type: "problem",
@@ -3146,11 +3589,11 @@ var prefer_read_only_props_default = createRule({
3146
3589
  messages: { default: "A function component's props should be read-only." },
3147
3590
  schema: []
3148
3591
  },
3149
- name: RULE_NAME$6,
3150
- create: create$6,
3592
+ name: RULE_NAME$4,
3593
+ create: create$4,
3151
3594
  defaultOptions: []
3152
3595
  });
3153
- function create$6(context) {
3596
+ function create$4(context) {
3154
3597
  const services = ESLintUtils.getParserServices(context, false);
3155
3598
  const checker = services.program.getTypeChecker();
3156
3599
  const { ctx, visitor } = core.useComponentCollector(context);
@@ -3191,7 +3634,7 @@ function isClassOrInterfaceReadonlyLoose(checker, type) {
3191
3634
 
3192
3635
  //#endregion
3193
3636
  //#region src/rules/prefer-use-state-lazy-initialization.ts
3194
- const RULE_NAME$5 = "prefer-use-state-lazy-initialization";
3637
+ const RULE_NAME$3 = "prefer-use-state-lazy-initialization";
3195
3638
  const ALLOW_LIST = [
3196
3639
  "Boolean",
3197
3640
  "String",
@@ -3204,11 +3647,11 @@ var prefer_use_state_lazy_initialization_default = createRule({
3204
3647
  messages: { default: "To prevent re-computation, consider using lazy initial state for useState calls that involve function calls. Ex: 'useState(() => getValue())'." },
3205
3648
  schema: []
3206
3649
  },
3207
- name: RULE_NAME$5,
3208
- create: create$5,
3650
+ name: RULE_NAME$3,
3651
+ create: create$3,
3209
3652
  defaultOptions: []
3210
3653
  });
3211
- function create$5(context) {
3654
+ function create$3(context) {
3212
3655
  return { CallExpression(node) {
3213
3656
  if (!core.isUseStateCall(node)) return;
3214
3657
  const [useStateInput] = node.arguments;
@@ -3236,170 +3679,220 @@ function create$5(context) {
3236
3679
  }
3237
3680
 
3238
3681
  //#endregion
3239
- //#region src/rules-removed/no-default-props.ts
3240
- const RULE_NAME$4 = "no-default-props";
3241
- var no_default_props_default = createRule({
3682
+ //#region src/rules/rules-of-hooks.ts
3683
+ const RULE_NAME$2 = "rules-of-hooks";
3684
+ var rules_of_hooks_default = createRule({
3242
3685
  meta: {
3243
3686
  type: "problem",
3244
- docs: { description: "Disallows the 'defaultProps' property in favor of ES6 default parameters." },
3245
- messages: { default: "[Deprecated] Use ES6 default parameters instead." },
3687
+ docs: { description: "Enforces the [Rules of Hooks](https://react.dev/reference/rules/rules-of-react#rules-of-hooks)." },
3688
+ messages: {
3689
+ afterEarlyReturn: "React Hook '{{name}}' is called after an early return. React Hooks must be called in the exact same order in every component render.",
3690
+ asyncHook: "React Hook '{{name}}' is called in an async function. React Hooks must be called in a synchronous React function component or custom Hook.",
3691
+ classHook: "React Hook '{{name}}' cannot be called in a class component. React Hooks can only be called in function components or custom Hooks.",
3692
+ conditionalHook: "React Hook '{{name}}' is called conditionally. React Hooks must be called in the exact same order in every component render.",
3693
+ invalidContext: "React Hook '{{name}}' is called in function '{{funcName}}' that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word 'use'.",
3694
+ loopHook: "React Hook '{{name}}' may be executed more than once. React Hooks must be called in the exact same order in every component render.",
3695
+ nestedHook: "React Hook '{{name}}' is called in a nested function. React Hooks must be called at the top level of a React function component or custom Hook.",
3696
+ topLevelHook: "React Hook '{{name}}' cannot be called at the top level. React Hooks must be called in a React function component or custom Hook.",
3697
+ useInTryCatch: "React Hook '{{name}}' cannot be called inside a try/catch block. To handle errors, wrap your component in an error boundary."
3698
+ },
3246
3699
  schema: []
3247
3700
  },
3248
- name: RULE_NAME$4,
3249
- create: create$4,
3701
+ name: RULE_NAME$2,
3702
+ create: create$2,
3250
3703
  defaultOptions: []
3251
3704
  });
3252
- function create$4(context) {
3253
- if (!context.sourceCode.text.includes("defaultProps")) return {};
3254
- return { AssignmentExpression(node) {
3255
- if (node.operator !== "=" || node.left.type !== AST_NODE_TYPES.MemberExpression) return;
3256
- const { object, property } = node.left;
3257
- if (object.type !== AST_NODE_TYPES.Identifier) return;
3258
- if (property.type !== AST_NODE_TYPES.Identifier || property.name !== "defaultProps") return;
3259
- if (!core.isComponentNameLoose(object.name)) return;
3260
- const variableNode = getVariableDefinitionNode(findVariable(object.name, context.sourceCode.getScope(node)), 0);
3261
- if (variableNode == null) return;
3262
- if (!ast.isFunction(variableNode)) return;
3263
- context.report({
3264
- messageId: "default",
3265
- node: property
3266
- });
3267
- } };
3705
+ function getHookName(node) {
3706
+ if (node.callee.type === AST_NODE_TYPES.Identifier) return node.callee.name;
3707
+ if (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier) return node.callee.property.name;
3708
+ return "unknown";
3268
3709
  }
3269
-
3270
- //#endregion
3271
- //#region src/rules-removed/no-forbidden-props.ts
3272
- const RULE_NAME$3 = "no-forbidden-props";
3273
- const defaultOptions = [{ forbid: [{ prop: "/_/" }] }];
3274
- var no_forbidden_props_default = createRule({
3275
- meta: {
3276
- type: "problem",
3277
- defaultOptions: [...defaultOptions],
3278
- deprecated: {
3279
- deprecatedSince: "2.3.2",
3280
- message: "This rule is deprecated and will be removed in future versions.",
3281
- replacedBy: [{ rule: {
3282
- name: "no-restricted-syntax",
3283
- url: "https://eslint.org/docs/latest/rules/no-restricted-syntax"
3284
- } }]
3285
- },
3286
- docs: { description: "Disallows certain props on components." },
3287
- messages: { default: "Prop \"{{name}}\" is forbidden." },
3288
- schema: [{
3289
- type: "object",
3290
- additionalProperties: false,
3291
- properties: { forbid: {
3292
- type: "array",
3293
- items: { anyOf: [
3294
- { type: "string" },
3295
- {
3296
- type: "object",
3297
- additionalProperties: false,
3298
- properties: {
3299
- excludedNodes: {
3300
- type: "array",
3301
- items: { type: "string" },
3302
- uniqueItems: true
3303
- },
3304
- prop: { type: "string" }
3305
- },
3306
- required: ["prop"]
3307
- },
3308
- {
3309
- type: "object",
3310
- additionalProperties: false,
3311
- properties: {
3312
- includedNodes: {
3313
- type: "array",
3314
- items: { type: "string" },
3315
- uniqueItems: true
3316
- },
3317
- prop: { type: "string" }
3318
- },
3319
- required: ["prop"]
3320
- }
3321
- ] }
3322
- } }
3323
- }]
3324
- },
3325
- name: RULE_NAME$3,
3326
- create: create$3,
3327
- defaultOptions
3328
- });
3329
- function create$3(context, [option]) {
3330
- const { forbid } = option;
3331
- return { JSXOpeningElement(node) {
3332
- let nodeName = null;
3333
- if (node.name.type === AST_NODE_TYPES.JSXIdentifier) nodeName = node.name.name;
3334
- else if (node.name.type === AST_NODE_TYPES.JSXNamespacedName) nodeName = node.name.name.name;
3335
- for (const attr of node.attributes) {
3336
- if (attr.type === AST_NODE_TYPES.JSXSpreadAttribute) continue;
3337
- const name = attr.name.name;
3338
- if (typeof name !== "string") continue;
3339
- for (const forbiddenPropItem of forbid) {
3340
- if (typeof forbiddenPropItem !== "string" && nodeName != null) {
3341
- if ("excludedNodes" in forbiddenPropItem && forbiddenPropItem.excludedNodes.includes(nodeName)) continue;
3342
- if ("includedNodes" in forbiddenPropItem && !forbiddenPropItem.includedNodes.includes(nodeName)) continue;
3710
+ function isUseCall(node) {
3711
+ if (node.callee.type === AST_NODE_TYPES.Identifier) return node.callee.name === "use";
3712
+ if (node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier) return node.callee.property.name === "use";
3713
+ return false;
3714
+ }
3715
+ function getFunctionEntryKind(node) {
3716
+ const id = ast.getFunctionId(node);
3717
+ if (id == null) return "other";
3718
+ if (id.type === AST_NODE_TYPES.Identifier) {
3719
+ if (core.isHookName(id.name)) return "hook";
3720
+ if (/^[A-Z]/.test(id.name)) return "component";
3721
+ }
3722
+ if (id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) {
3723
+ if (core.isHookName(id.property.name)) return "hook";
3724
+ if (/^[A-Z]/.test(id.property.name)) return "component";
3725
+ }
3726
+ return "other";
3727
+ }
3728
+ function isConditionalNode(node) {
3729
+ return node.type === AST_NODE_TYPES.IfStatement || node.type === AST_NODE_TYPES.SwitchStatement || node.type === AST_NODE_TYPES.ConditionalExpression || node.type === AST_NODE_TYPES.LogicalExpression;
3730
+ }
3731
+ function isLoopNode(node) {
3732
+ return node.type === AST_NODE_TYPES.ForStatement || node.type === AST_NODE_TYPES.ForInStatement || node.type === AST_NODE_TYPES.ForOfStatement || node.type === AST_NODE_TYPES.WhileStatement || node.type === AST_NODE_TYPES.DoWhileStatement;
3733
+ }
3734
+ function isTryCatchNode(node) {
3735
+ return node.type === AST_NODE_TYPES.TryStatement;
3736
+ }
3737
+ function create$2(context) {
3738
+ const functionStack = [];
3739
+ function findEnclosingComponentOrHook() {
3740
+ for (let i = functionStack.length - 1; i >= 0; i--) {
3741
+ const entry = functionStack[i];
3742
+ if (entry == null) continue;
3743
+ if (entry.kind === "component" || entry.kind === "hook") return entry;
3744
+ }
3745
+ }
3746
+ function checkHookCall(node) {
3747
+ const hookName = getHookName(node);
3748
+ const isUse = isUseCall(node);
3749
+ if (functionStack.length === 0) {
3750
+ context.report({
3751
+ messageId: "topLevelHook",
3752
+ node,
3753
+ data: { name: hookName }
3754
+ });
3755
+ return;
3756
+ }
3757
+ const boundary = findEnclosingComponentOrHook();
3758
+ if (boundary == null) {
3759
+ if (ast.findParentNode(node, ast.isClass) != null) {
3760
+ context.report({
3761
+ messageId: "classHook",
3762
+ node,
3763
+ data: { name: hookName }
3764
+ });
3765
+ return;
3766
+ }
3767
+ const currentEntry = functionStack.at(-1);
3768
+ if (currentEntry == null) return;
3769
+ const funcId = ast.getFunctionId(currentEntry.node);
3770
+ const funcName = funcId != null && funcId.type === AST_NODE_TYPES.Identifier ? funcId.name : "anonymous";
3771
+ context.report({
3772
+ messageId: "invalidContext",
3773
+ node,
3774
+ data: {
3775
+ name: hookName,
3776
+ funcName
3343
3777
  }
3344
- if (toRegExp(typeof forbiddenPropItem === "string" ? forbiddenPropItem : forbiddenPropItem.prop).test(name)) context.report({
3345
- messageId: "default",
3346
- node: attr,
3347
- data: { name }
3778
+ });
3779
+ return;
3780
+ }
3781
+ const currentEntry = functionStack.at(-1);
3782
+ if (currentEntry != null && currentEntry.isAsync) {
3783
+ context.report({
3784
+ messageId: "asyncHook",
3785
+ node,
3786
+ data: { name: hookName }
3787
+ });
3788
+ return;
3789
+ }
3790
+ if (boundary.isAsync) {
3791
+ context.report({
3792
+ messageId: "asyncHook",
3793
+ node,
3794
+ data: { name: hookName }
3795
+ });
3796
+ return;
3797
+ }
3798
+ let current = node.parent;
3799
+ while (current != null && current !== boundary.node) {
3800
+ if (ast.isClass(current)) {
3801
+ context.report({
3802
+ messageId: "classHook",
3803
+ node,
3804
+ data: { name: hookName }
3805
+ });
3806
+ return;
3807
+ }
3808
+ if (ast.isFunction(current) && current !== boundary.node) {
3809
+ const nestedKind = getFunctionEntryKind(current);
3810
+ if (nestedKind === "component" || nestedKind === "hook") break;
3811
+ context.report({
3812
+ messageId: "nestedHook",
3813
+ node,
3814
+ data: { name: hookName }
3815
+ });
3816
+ return;
3817
+ }
3818
+ if (!isUse && isConditionalNode(current)) {
3819
+ context.report({
3820
+ messageId: "conditionalHook",
3821
+ node,
3822
+ data: { name: hookName }
3823
+ });
3824
+ return;
3825
+ }
3826
+ if (!isUse && isLoopNode(current)) {
3827
+ context.report({
3828
+ messageId: "loopHook",
3829
+ node,
3830
+ data: { name: hookName }
3831
+ });
3832
+ return;
3833
+ }
3834
+ if (isUse && isTryCatchNode(current)) {
3835
+ context.report({
3836
+ messageId: "useInTryCatch",
3837
+ node,
3838
+ data: { name: hookName }
3348
3839
  });
3840
+ return;
3349
3841
  }
3842
+ current = current.parent;
3350
3843
  }
3351
- } };
3352
- }
3353
-
3354
- //#endregion
3355
- //#region src/rules-removed/no-prop-types.ts
3356
- const RULE_NAME$2 = "no-prop-types";
3357
- var no_prop_types_default = createRule({
3358
- meta: {
3359
- type: "problem",
3360
- docs: { description: "Disallows 'propTypes' in favor of TypeScript or another type-checking solution." },
3361
- messages: { default: "[Deprecated] Use TypeScript or another type-checking solution instead." },
3362
- schema: []
3363
- },
3364
- name: RULE_NAME$2,
3365
- create: create$2,
3366
- defaultOptions: []
3367
- });
3368
- function create$2(context) {
3369
- if (!context.sourceCode.text.includes("propTypes")) return {};
3844
+ if (boundary.hasEarlyReturn) {
3845
+ context.report({
3846
+ messageId: "afterEarlyReturn",
3847
+ node,
3848
+ data: { name: hookName }
3849
+ });
3850
+ return;
3851
+ }
3852
+ }
3370
3853
  return {
3371
- AssignmentExpression(node) {
3372
- if (node.operator !== "=" || node.left.type !== AST_NODE_TYPES.MemberExpression) return;
3373
- const { object, property } = node.left;
3374
- if (object.type !== AST_NODE_TYPES.Identifier) return;
3375
- if (property.type !== AST_NODE_TYPES.Identifier || property.name !== "propTypes") return;
3376
- if (!core.isComponentNameLoose(object.name)) return;
3377
- const variableNode = getVariableDefinitionNode(findVariable(object.name, context.sourceCode.getScope(node)), 0);
3378
- if (variableNode != null && (ast.isFunction(variableNode) || core.isClassComponent(variableNode))) context.report({
3379
- messageId: "default",
3380
- node: property
3854
+ ":function"(node) {
3855
+ const kind = getFunctionEntryKind(node);
3856
+ functionStack.push({
3857
+ kind,
3858
+ node,
3859
+ hasEarlyReturn: false,
3860
+ isAsync: node.async
3381
3861
  });
3382
3862
  },
3383
- PropertyDefinition(node) {
3384
- if (!core.isClassComponent(node.parent.parent)) return;
3385
- if (!node.static || node.key.type !== AST_NODE_TYPES.Identifier || node.key.name !== "propTypes") return;
3386
- context.report({
3387
- messageId: "default",
3388
- node
3389
- });
3863
+ ":function:exit"() {
3864
+ functionStack.pop();
3865
+ },
3866
+ CallExpression(node) {
3867
+ if (!core.isHookCall(node)) return;
3868
+ checkHookCall(node);
3869
+ },
3870
+ ReturnStatement(node) {
3871
+ if (functionStack.length === 0) return;
3872
+ const entry = functionStack.at(-1);
3873
+ if (entry == null) return;
3874
+ const fnNode = entry.node;
3875
+ if (fnNode.body.type !== AST_NODE_TYPES.BlockStatement) return;
3876
+ const body = fnNode.body.body;
3877
+ let stmt = node;
3878
+ while (stmt.parent !== fnNode.body) {
3879
+ if (stmt.parent == null) return;
3880
+ stmt = stmt.parent;
3881
+ }
3882
+ const idx = body.indexOf(stmt);
3883
+ if (idx !== -1 && idx < body.length - 1) entry.hasEarlyReturn = true;
3390
3884
  }
3391
3885
  };
3392
3886
  }
3393
3887
 
3394
3888
  //#endregion
3395
- //#region src/rules-removed/no-string-refs.ts
3396
- const RULE_NAME$1 = "no-string-refs";
3397
- var no_string_refs_default = createRule({
3889
+ //#region src/rules/set-state-in-effect.ts
3890
+ const RULE_NAME$1 = "set-state-in-effect";
3891
+ var set_state_in_effect_default = createRule({
3398
3892
  meta: {
3399
3893
  type: "problem",
3400
- docs: { description: "Replaces string refs with callback refs." },
3401
- fixable: "code",
3402
- messages: { default: "[Deprecated] Use callback refs instead." },
3894
+ docs: { description: "Validates against calling ['setState'](https://react.dev/reference/react/useState#setstate) synchronously in an effect, which can lead to re-renders that degrade performance." },
3895
+ messages: { default: "Do not call the 'set' function '{{name}}' of 'useState' synchronously in an effect. This can lead to unnecessary re-renders and performance issues." },
3403
3896
  schema: []
3404
3897
  },
3405
3898
  name: RULE_NAME$1,
@@ -3407,56 +3900,203 @@ var no_string_refs_default = createRule({
3407
3900
  defaultOptions: []
3408
3901
  });
3409
3902
  function create$1(context) {
3410
- const state = { isWithinClassComponent: false };
3411
- function onClassBodyEnter(node) {
3412
- if (core.isClassComponent(node.parent)) state.isWithinClassComponent = true;
3903
+ if (!/use\w*Effect/u.test(context.sourceCode.text)) return {};
3904
+ const { additionalStateHooks } = getSettingsFromContext(context);
3905
+ const functionEntries = [];
3906
+ const setupFnRef = { current: null };
3907
+ const setupFnIds = [];
3908
+ const trackedFnCalls = [];
3909
+ const setStateCallsByFn = /* @__PURE__ */ new WeakMap();
3910
+ const setStateInEffectArg = /* @__PURE__ */ new WeakMap();
3911
+ const setStateInEffectSetup = /* @__PURE__ */ new Map();
3912
+ const setStateInHookCallbacks = /* @__PURE__ */ new WeakMap();
3913
+ const getText = (n) => context.sourceCode.getText(n);
3914
+ const onSetupFunctionEnter = (node) => {
3915
+ setupFnRef.current = node;
3916
+ };
3917
+ const onSetupFunctionExit = (node) => {
3918
+ if (setupFnRef.current === node) setupFnRef.current = null;
3919
+ };
3920
+ function isThenCall(node) {
3921
+ return node.callee.type === AST_NODE_TYPES.MemberExpression && node.callee.property.type === AST_NODE_TYPES.Identifier && node.callee.property.name === "then";
3413
3922
  }
3414
- function onClassBodyExit() {
3415
- state.isWithinClassComponent = false;
3923
+ function isUseStateCall(node) {
3924
+ return core.isUseStateLikeCall(node, additionalStateHooks);
3925
+ }
3926
+ function isUseEffectSetupCallback(node) {
3927
+ return node.parent?.type === AST_NODE_TYPES.CallExpression && node.parent.callee !== node && core.isUseEffectLikeCall(node.parent);
3928
+ }
3929
+ function getCallName(node) {
3930
+ if (node.type === AST_NODE_TYPES.CallExpression) return ast.getFullyQualifiedName(node.callee, getText);
3931
+ return ast.getFullyQualifiedName(node, getText);
3932
+ }
3933
+ function getCallKind(node) {
3934
+ return match(node).when(isUseStateCall, () => "useState").when(core.isUseEffectLikeCall, () => "useEffect").when(isSetStateCall, () => "setState").when(isThenCall, () => "then").otherwise(() => "other");
3935
+ }
3936
+ function getFunctionKind(node) {
3937
+ const parent = ast.findParentNode(node, not(ast.isTypeExpression)) ?? node.parent;
3938
+ switch (true) {
3939
+ case node.async:
3940
+ case parent.type === AST_NODE_TYPES.CallExpression && isThenCall(parent): return "deferred";
3941
+ case node.type !== AST_NODE_TYPES.FunctionDeclaration && parent.type === AST_NODE_TYPES.CallExpression && parent.callee === node: return "immediate";
3942
+ case isUseEffectSetupCallback(node): return "setup";
3943
+ default: return "other";
3944
+ }
3945
+ }
3946
+ function isIdFromUseStateCall(topLevelId, at) {
3947
+ const variableNode = getVariableDefinitionNode(findVariable(topLevelId, context.sourceCode.getScope(topLevelId)), 0);
3948
+ if (variableNode == null) return false;
3949
+ if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
3950
+ if (!isUseStateCall(variableNode)) return false;
3951
+ const variableNodeParent = variableNode.parent;
3952
+ if (!("id" in variableNodeParent) || variableNodeParent.id?.type !== AST_NODE_TYPES.ArrayPattern) return true;
3953
+ return variableNodeParent.id.elements.findIndex((e) => e?.type === AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === at;
3954
+ }
3955
+ function isSetStateCall(node) {
3956
+ switch (node.callee.type) {
3957
+ case AST_NODE_TYPES.CallExpression: {
3958
+ const { callee } = node.callee;
3959
+ if (callee.type !== AST_NODE_TYPES.MemberExpression) return false;
3960
+ if (!("name" in callee.object)) return false;
3961
+ const isAt = callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "at";
3962
+ const [index] = node.callee.arguments;
3963
+ if (!isAt || index == null) return false;
3964
+ return getStaticValue(index, context.sourceCode.getScope(node))?.value === 1 && isIdFromUseStateCall(callee.object);
3965
+ }
3966
+ case AST_NODE_TYPES.Identifier: return isIdFromUseStateCall(node.callee, 1);
3967
+ case AST_NODE_TYPES.MemberExpression: {
3968
+ if (!("name" in node.callee.object)) return false;
3969
+ const property = node.callee.property;
3970
+ return getStaticValue(property, context.sourceCode.getScope(node))?.value === 1 && isIdFromUseStateCall(node.callee.object, 1);
3971
+ }
3972
+ default: return false;
3973
+ }
3416
3974
  }
3417
3975
  return {
3418
- ClassBody: onClassBodyEnter,
3419
- "ClassBody:exit": onClassBodyExit,
3420
- JSXAttribute(node) {
3421
- if (node.name.name !== "ref") return;
3422
- const refName = getJsxAttributeValueText(context, node.value);
3423
- if (refName == null) return;
3424
- context.report({
3425
- messageId: "default",
3426
- node,
3427
- fix(fixer) {
3428
- if (node.value == null) return null;
3429
- if (!state.isWithinClassComponent) return null;
3430
- return fixer.replaceText(node.value, `{(ref) => { this.refs[${refName}] = ref; }}`);
3976
+ ":function"(node) {
3977
+ const kind = getFunctionKind(node);
3978
+ functionEntries.push({
3979
+ kind,
3980
+ node
3981
+ });
3982
+ if (kind === "setup") onSetupFunctionEnter(node);
3983
+ },
3984
+ ":function:exit"(node) {
3985
+ const { kind } = functionEntries.at(-1) ?? {};
3986
+ if (kind === "setup") onSetupFunctionExit(node);
3987
+ functionEntries.pop();
3988
+ },
3989
+ CallExpression(node) {
3990
+ const setupFunction = setupFnRef.current;
3991
+ const entry = functionEntries.at(-1);
3992
+ if (entry == null || entry.node.async) return;
3993
+ match(getCallKind(node)).with("setState", () => {
3994
+ switch (true) {
3995
+ case entry.kind === "deferred":
3996
+ case entry.node.async: break;
3997
+ case entry.node === setupFunction:
3998
+ case entry.kind === "immediate" && ast.findParentNode(entry.node, ast.isFunction) === setupFunction:
3999
+ context.report({
4000
+ messageId: "default",
4001
+ node,
4002
+ data: { name: context.sourceCode.getText(node.callee) }
4003
+ });
4004
+ return;
4005
+ default: {
4006
+ const init = ast.findParentNode(node, isVariableDeclaratorFromHookCall)?.init;
4007
+ if (init == null) getOrElseUpdate(setStateCallsByFn, entry.node, () => []).push(node);
4008
+ else getOrElseUpdate(setStateInHookCallbacks, init, () => []).push(node);
4009
+ }
4010
+ }
4011
+ }).with("useEffect", () => {
4012
+ if (ast.isFunction(node.arguments.at(0))) return;
4013
+ setupFnIds.push(...ast.getNestedIdentifiers(node));
4014
+ }).with("other", () => {
4015
+ if (entry.node !== setupFunction) return;
4016
+ trackedFnCalls.push(node);
4017
+ }).otherwise(constVoid);
4018
+ },
4019
+ Identifier(node) {
4020
+ if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) return;
4021
+ if (!isIdFromUseStateCall(node, 1)) return;
4022
+ switch (node.parent.type) {
4023
+ case AST_NODE_TYPES.ArrowFunctionExpression: {
4024
+ const parent = node.parent.parent;
4025
+ if (parent.type !== AST_NODE_TYPES.CallExpression) break;
4026
+ if (!core.isUseMemoCall(parent)) break;
4027
+ const init = ast.findParentNode(parent, isVariableDeclaratorFromHookCall)?.init;
4028
+ if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
4029
+ break;
4030
+ }
4031
+ case AST_NODE_TYPES.CallExpression:
4032
+ if (node !== node.parent.arguments.at(0)) break;
4033
+ if (core.isUseCallbackCall(node.parent)) {
4034
+ const init = ast.findParentNode(node.parent, isVariableDeclaratorFromHookCall)?.init;
4035
+ if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
4036
+ break;
4037
+ }
4038
+ if (core.isUseEffectLikeCall(node.parent)) getOrElseUpdate(setStateInEffectSetup, node.parent, () => []).push(node);
4039
+ }
4040
+ },
4041
+ "Program:exit"() {
4042
+ const getSetStateCalls = (id, initialScope) => {
4043
+ const node = getVariableDefinitionNode(findVariable(id, initialScope), 0);
4044
+ switch (node?.type) {
4045
+ case AST_NODE_TYPES.ArrowFunctionExpression:
4046
+ case AST_NODE_TYPES.FunctionDeclaration:
4047
+ case AST_NODE_TYPES.FunctionExpression: return setStateCallsByFn.get(node) ?? [];
4048
+ case AST_NODE_TYPES.CallExpression: return setStateInHookCallbacks.get(node) ?? setStateInEffectArg.get(node) ?? [];
3431
4049
  }
4050
+ return [];
4051
+ };
4052
+ for (const [, calls] of setStateInEffectSetup) for (const call of calls) context.report({
4053
+ messageId: "default",
4054
+ node: call,
4055
+ data: { name: call.name }
3432
4056
  });
4057
+ for (const { callee } of trackedFnCalls) {
4058
+ if (!("name" in callee)) continue;
4059
+ const { name } = callee;
4060
+ const setStateCalls = getSetStateCalls(name, context.sourceCode.getScope(callee));
4061
+ for (const setStateCall of setStateCalls) context.report({
4062
+ messageId: "default",
4063
+ node: setStateCall,
4064
+ data: { name: getCallName(setStateCall) }
4065
+ });
4066
+ }
4067
+ for (const id of setupFnIds) {
4068
+ const setStateCalls = getSetStateCalls(id.name, context.sourceCode.getScope(id));
4069
+ for (const setStateCall of setStateCalls) context.report({
4070
+ messageId: "default",
4071
+ node: setStateCall,
4072
+ data: { name: getCallName(setStateCall) }
4073
+ });
4074
+ }
3433
4075
  }
3434
4076
  };
3435
4077
  }
3436
- /**
3437
- * Extracts the text content from a JSX attribute's value
3438
- * @param context The rule context
3439
- * @param node The JSX attribute value node
3440
- * @returns The text of the attribute value, or null if not a string-like value
3441
- */
3442
- function getJsxAttributeValueText(context, node) {
3443
- if (node == null) return null;
3444
- switch (true) {
3445
- case node.type === AST_NODE_TYPES.Literal && typeof node.value === "string": return context.sourceCode.getText(node);
3446
- case node.type === AST_NODE_TYPES.JSXExpressionContainer && node.expression.type === AST_NODE_TYPES.Literal && typeof node.expression.value === "string": return context.sourceCode.getText(node.expression);
3447
- case node.type === AST_NODE_TYPES.JSXExpressionContainer && node.expression.type === AST_NODE_TYPES.TemplateLiteral: return context.sourceCode.getText(node.expression);
3448
- default: return null;
4078
+ function isInitFromHookCall(init) {
4079
+ if (init?.type !== AST_NODE_TYPES.CallExpression) return false;
4080
+ switch (init.callee.type) {
4081
+ case AST_NODE_TYPES.Identifier: return core.isHookName(init.callee.name);
4082
+ case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && core.isHookName(init.callee.property.name);
4083
+ default: return false;
3449
4084
  }
3450
4085
  }
4086
+ function isVariableDeclaratorFromHookCall(node) {
4087
+ if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
4088
+ if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
4089
+ return isInitFromHookCall(node.init);
4090
+ }
3451
4091
 
3452
4092
  //#endregion
3453
- //#region src/rules-removed/no-unnecessary-use-ref.ts
3454
- const RULE_NAME = "no-unnecessary-use-ref";
3455
- var no_unnecessary_use_ref_default = createRule({
4093
+ //#region src/rules/set-state-in-render.ts
4094
+ const RULE_NAME = "set-state-in-render";
4095
+ var set_state_in_render_default = createRule({
3456
4096
  meta: {
3457
4097
  type: "problem",
3458
- docs: { description: "Disallows unnecessary usage of 'useRef'." },
3459
- messages: { default: "Unnecessary use of 'useRef'. Instead, co-locate the value inside the effect that uses it." },
4098
+ docs: { description: "Validates against unconditionally setting state during render, which can trigger additional renders and potential infinite render loops." },
4099
+ messages: { default: "Do not call the 'set' function '{{name}}' unconditionally during render. This will trigger an infinite render loop." },
3460
4100
  schema: []
3461
4101
  },
3462
4102
  name: RULE_NAME,
@@ -3464,27 +4104,126 @@ var no_unnecessary_use_ref_default = createRule({
3464
4104
  defaultOptions: []
3465
4105
  });
3466
4106
  function create(context) {
3467
- if (!context.sourceCode.text.includes("useRef")) return {};
3468
- return { VariableDeclarator(node) {
3469
- const { id, init } = node;
3470
- if (id.type !== AST_NODE_TYPES.Identifier || init == null || !core.isUseRefCall(init)) return;
3471
- const [ref, ...rest] = context.sourceCode.getDeclaredVariables(node);
3472
- if (ref == null || rest.length > 0) return;
3473
- if (ref.name.toLowerCase().startsWith("prev")) return;
3474
- const effects = /* @__PURE__ */ new Set();
3475
- let globalUsages = 0;
3476
- for (const { identifier, init } of ref.references) {
3477
- if (init != null) continue;
3478
- const effect = ast.findParentNode(identifier, core.isUseEffectLikeCall);
3479
- if (effect == null) globalUsages++;
3480
- else effects.add(effect);
3481
- }
3482
- if (globalUsages > 0 || effects.size !== 1) return;
3483
- context.report({
3484
- messageId: "default",
3485
- node: node.parent
3486
- });
3487
- } };
4107
+ const { additionalStateHooks } = getSettingsFromContext(context);
4108
+ const functionEntries = [];
4109
+ const componentFnRef = { current: null };
4110
+ const componentHasEarlyReturn = { current: false };
4111
+ function isUseStateCall(node) {
4112
+ return core.isUseStateLikeCall(node, additionalStateHooks);
4113
+ }
4114
+ function isIdFromUseStateCall(topLevelId, at) {
4115
+ const variableNode = getVariableDefinitionNode(findVariable(topLevelId, context.sourceCode.getScope(topLevelId)), 0);
4116
+ if (variableNode == null) return false;
4117
+ if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
4118
+ if (!isUseStateCall(variableNode)) return false;
4119
+ const variableNodeParent = variableNode.parent;
4120
+ if (!("id" in variableNodeParent) || variableNodeParent.id?.type !== AST_NODE_TYPES.ArrayPattern) return true;
4121
+ return variableNodeParent.id.elements.findIndex((e) => e?.type === AST_NODE_TYPES.Identifier && e.name === topLevelId.name) === at;
4122
+ }
4123
+ function isSetStateCall(node) {
4124
+ switch (node.callee.type) {
4125
+ case AST_NODE_TYPES.CallExpression: {
4126
+ const { callee } = node.callee;
4127
+ if (callee.type !== AST_NODE_TYPES.MemberExpression) return false;
4128
+ if (!("name" in callee.object)) return false;
4129
+ const isAt = callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "at";
4130
+ const [index] = node.callee.arguments;
4131
+ if (!isAt || index == null) return false;
4132
+ return getStaticValue(index, context.sourceCode.getScope(node))?.value === 1 && isIdFromUseStateCall(callee.object);
4133
+ }
4134
+ case AST_NODE_TYPES.Identifier: return isIdFromUseStateCall(node.callee, 1);
4135
+ case AST_NODE_TYPES.MemberExpression: {
4136
+ if (!("name" in node.callee.object)) return false;
4137
+ const property = node.callee.property;
4138
+ return getStaticValue(property, context.sourceCode.getScope(node))?.value === 1 && isIdFromUseStateCall(node.callee.object, 1);
4139
+ }
4140
+ default: return false;
4141
+ }
4142
+ }
4143
+ function isInsideConditional(node, stopAt) {
4144
+ let current = node.parent;
4145
+ while (current != null && current !== stopAt) {
4146
+ switch (current.type) {
4147
+ case AST_NODE_TYPES.IfStatement:
4148
+ case AST_NODE_TYPES.ConditionalExpression:
4149
+ case AST_NODE_TYPES.LogicalExpression:
4150
+ case AST_NODE_TYPES.SwitchStatement:
4151
+ case AST_NODE_TYPES.SwitchCase: return true;
4152
+ default: break;
4153
+ }
4154
+ current = current.parent;
4155
+ }
4156
+ return false;
4157
+ }
4158
+ function isInsideEventHandler(node, stopAt) {
4159
+ let current = node.parent;
4160
+ while (current != null && current !== stopAt) {
4161
+ if (ast.isFunction(current) && current !== stopAt) return true;
4162
+ current = current.parent;
4163
+ }
4164
+ return false;
4165
+ }
4166
+ function isComponentLikeFunction(node) {
4167
+ const id = ast.getFunctionId(node);
4168
+ if (id == null) return false;
4169
+ if (id.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.name);
4170
+ if (id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.property.name);
4171
+ return false;
4172
+ }
4173
+ function getFunctionKind(node) {
4174
+ if (isComponentLikeFunction(node)) return "component";
4175
+ const parent = ast.findParentNode(node, not(ast.isTypeExpression)) ?? node.parent;
4176
+ if (parent.type === AST_NODE_TYPES.CallExpression && parent.callee !== node) return "callback";
4177
+ return "other";
4178
+ }
4179
+ return {
4180
+ ":function"(node) {
4181
+ const kind = getFunctionKind(node);
4182
+ functionEntries.push({
4183
+ kind,
4184
+ node
4185
+ });
4186
+ if (kind === "component") {
4187
+ componentFnRef.current = node;
4188
+ componentHasEarlyReturn.current = false;
4189
+ }
4190
+ },
4191
+ ":function:exit"(node) {
4192
+ if (functionEntries.at(-1)?.kind === "component" && componentFnRef.current === node) {
4193
+ componentFnRef.current = null;
4194
+ componentHasEarlyReturn.current = false;
4195
+ }
4196
+ functionEntries.pop();
4197
+ },
4198
+ CallExpression(node) {
4199
+ const componentFn = componentFnRef.current;
4200
+ if (componentFn == null) return;
4201
+ if (!isSetStateCall(node)) return;
4202
+ if (isInsideEventHandler(node, componentFn)) return;
4203
+ if (isInsideConditional(node, componentFn)) return;
4204
+ if (componentHasEarlyReturn.current) return;
4205
+ context.report({
4206
+ messageId: "default",
4207
+ node,
4208
+ data: { name: context.sourceCode.getText(node.callee) }
4209
+ });
4210
+ },
4211
+ ReturnStatement(node) {
4212
+ const componentFn = componentFnRef.current;
4213
+ if (componentFn == null) return;
4214
+ const entry = functionEntries.at(-1);
4215
+ if (entry == null || entry.node !== componentFn) return;
4216
+ if (componentFn.body.type !== AST_NODE_TYPES.BlockStatement) return;
4217
+ const body = componentFn.body.body;
4218
+ let stmt = node;
4219
+ while (stmt.parent !== componentFn.body) {
4220
+ if (stmt.parent == null) return;
4221
+ stmt = stmt.parent;
4222
+ }
4223
+ const idx = body.indexOf(stmt);
4224
+ if (idx !== -1 && idx < body.length - 1) componentHasEarlyReturn.current = true;
4225
+ }
4226
+ };
3488
4227
  }
3489
4228
 
3490
4229
  //#endregion
@@ -3495,6 +4234,9 @@ const plugin = {
3495
4234
  version
3496
4235
  },
3497
4236
  rules: {
4237
+ "component-hook-factories": component_hook_factories_default,
4238
+ "error-boundaries": error_boundaries_default,
4239
+ "exhaustive-deps": exhaustive_deps_default,
3498
4240
  "jsx-dollar": jsx_dollar_default,
3499
4241
  "jsx-key-before-spread": jsx_key_before_spread_default,
3500
4242
  "jsx-no-comment-textnodes": jsx_no_comment_textnodes_default,
@@ -3535,7 +4277,6 @@ const plugin = {
3535
4277
  "no-set-state-in-component-did-mount": no_set_state_in_component_did_mount_default,
3536
4278
  "no-set-state-in-component-did-update": no_set_state_in_component_did_update_default,
3537
4279
  "no-set-state-in-component-will-update": no_set_state_in_component_will_update_default,
3538
- "no-unnecessary-key": no_unnecessary_key_default,
3539
4280
  "no-unnecessary-use-callback": no_unnecessary_use_callback_default,
3540
4281
  "no-unnecessary-use-memo": no_unnecessary_use_memo_default,
3541
4282
  "no-unnecessary-use-prefix": no_unnecessary_use_prefix_default,
@@ -3554,11 +4295,9 @@ const plugin = {
3554
4295
  "prefer-namespace-import": prefer_namespace_import_default,
3555
4296
  "prefer-read-only-props": prefer_read_only_props_default,
3556
4297
  "prefer-use-state-lazy-initialization": prefer_use_state_lazy_initialization_default,
3557
- "no-default-props": no_default_props_default,
3558
- "no-forbidden-props": no_forbidden_props_default,
3559
- "no-prop-types": no_prop_types_default,
3560
- "no-string-refs": no_string_refs_default,
3561
- "no-unnecessary-use-ref": no_unnecessary_use_ref_default
4298
+ "rules-of-hooks": rules_of_hooks_default,
4299
+ "set-state-in-effect": set_state_in_effect_default,
4300
+ "set-state-in-render": set_state_in_render_default
3562
4301
  }
3563
4302
  };
3564
4303
 
@@ -3572,6 +4311,9 @@ var recommended_exports = /* @__PURE__ */ __exportAll({
3572
4311
  });
3573
4312
  const name$5 = "react-x/recommended";
3574
4313
  const rules$6 = {
4314
+ "react-x/component-hook-factories": "error",
4315
+ "react-x/error-boundaries": "error",
4316
+ "react-x/exhaustive-deps": "warn",
3575
4317
  "react-x/jsx-key-before-spread": "warn",
3576
4318
  "react-x/jsx-no-comment-textnodes": "warn",
3577
4319
  "react-x/jsx-no-duplicate-props": "warn",
@@ -3590,25 +4332,25 @@ const rules$6 = {
3590
4332
  "react-x/no-component-will-update": "error",
3591
4333
  "react-x/no-context-provider": "warn",
3592
4334
  "react-x/no-create-ref": "error",
3593
- "react-x/no-default-props": "error",
3594
4335
  "react-x/no-direct-mutation-state": "error",
3595
4336
  "react-x/no-forward-ref": "warn",
3596
4337
  "react-x/no-missing-key": "error",
3597
4338
  "react-x/no-nested-component-definitions": "error",
3598
4339
  "react-x/no-nested-lazy-component-declarations": "error",
3599
- "react-x/no-prop-types": "error",
3600
4340
  "react-x/no-redundant-should-component-update": "error",
3601
4341
  "react-x/no-set-state-in-component-did-mount": "warn",
3602
4342
  "react-x/no-set-state-in-component-did-update": "warn",
3603
4343
  "react-x/no-set-state-in-component-will-update": "warn",
3604
- "react-x/no-string-refs": "error",
3605
4344
  "react-x/no-unnecessary-use-prefix": "warn",
3606
4345
  "react-x/no-unsafe-component-will-mount": "warn",
3607
4346
  "react-x/no-unsafe-component-will-receive-props": "warn",
3608
4347
  "react-x/no-unsafe-component-will-update": "warn",
3609
4348
  "react-x/no-use-context": "warn",
3610
4349
  "react-x/no-useless-forward-ref": "warn",
3611
- "react-x/prefer-use-state-lazy-initialization": "warn"
4350
+ "react-x/prefer-use-state-lazy-initialization": "warn",
4351
+ "react-x/rules-of-hooks": "error",
4352
+ "react-x/set-state-in-effect": "warn",
4353
+ "react-x/set-state-in-render": "error"
3612
4354
  };
3613
4355
  const plugins$5 = { "react-x": plugin };
3614
4356
  const settings$5 = { "react-x": DEFAULT_ESLINT_REACT_SETTINGS };