eslint-plugin-react-x 3.0.0-next.2 → 3.0.0-next.23

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 +935 -498
  2. package/package.json +12 -11
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { ESLintUtils } from "@typescript-eslint/utils";
5
5
  import { P, isMatching, match } from "ts-pattern";
6
6
  import ts from "typescript";
7
7
  import { AST_NODE_TYPES } from "@typescript-eslint/types";
8
- import { findEnclosingAssignmentTarget, findVariable, getChildScopes, getObjectType, getVariableDefinitionNode, isAssignmentTargetEqual } from "@eslint-react/var";
8
+ import { findEnclosingAssignmentTarget, findVariable, getChildScopes, getObjectType, getVariableInitializer, isAssignmentTargetEqual } from "@eslint-react/var";
9
9
  import { DefinitionType } from "@typescript-eslint/scope-manager";
10
10
  import { constFalse, constTrue, constVoid, flow, getOrElseUpdate, identity, not, unit } from "@eslint-react/eff";
11
11
  import { compare } from "compare-versions";
@@ -13,6 +13,7 @@ import { getConstrainedTypeAtLocation, isTypeReadonly } from "@typescript-eslint
13
13
  import { isPropertyReadonlyInType, unionConstituents } from "ts-api-utils";
14
14
  import { getStaticValue, isIdentifier, isVariableDeclarator } from "@typescript-eslint/utils/ast-utils";
15
15
  import { getTypeImmutability, isImmutable, isReadonlyDeep, isReadonlyShallow, isUnknown } from "is-immutable-type";
16
+ import { snakeCase } from "string-ts";
16
17
 
17
18
  //#region \0rolldown/runtime.js
18
19
  var __defProp = Object.defineProperty;
@@ -38,15 +39,18 @@ var disable_experimental_exports = /* @__PURE__ */ __exportAll({
38
39
  });
39
40
  const name$8 = "react-x/disable-experimental";
40
41
  const rules$8 = {
42
+ "react-x/exhaustive-deps": "off",
41
43
  "react-x/jsx-key-before-spread": "off",
42
- "react-x/jsx-no-iife": "off",
43
44
  "react-x/no-duplicate-key": "off",
44
45
  "react-x/no-implicit-key": "off",
45
46
  "react-x/no-misused-capture-owner-stack": "off",
46
47
  "react-x/no-unnecessary-use-callback": "off",
47
48
  "react-x/no-unnecessary-use-memo": "off",
48
49
  "react-x/no-unused-props": "off",
49
- "react-x/prefer-read-only-props": "off"
50
+ "react-x/prefer-read-only-props": "off",
51
+ "react-x/refs": "off",
52
+ "react-x/rules-of-hooks": "off",
53
+ "react-x/set-state-in-render": "off"
50
54
  };
51
55
 
52
56
  //#endregion
@@ -66,7 +70,7 @@ const rules$7 = {
66
70
  //#endregion
67
71
  //#region package.json
68
72
  var name$6 = "eslint-plugin-react-x";
69
- var version = "3.0.0-next.2";
73
+ var version = "3.0.0-next.23";
70
74
 
71
75
  //#endregion
72
76
  //#region src/utils/create-rule.ts
@@ -136,7 +140,6 @@ function getFullyQualifiedNameEx(checker, symbol) {
136
140
  let name = symbol.name;
137
141
  let parent = symbol.declarations?.at(0)?.parent;
138
142
  if (parent == null) return checker.getFullyQualifiedName(symbol);
139
- const namespace = parent.getSourceFile().statements.find((n) => ts.isNamespaceExportDeclaration(n));
140
143
  while (parent.kind !== ts.SyntaxKind.SourceFile) {
141
144
  switch (true) {
142
145
  case ts.isInterfaceDeclaration(parent):
@@ -168,11 +171,14 @@ function getFullyQualifiedNameEx(checker, symbol) {
168
171
  case ts.isObjectLiteralExpression(parent):
169
172
  case ts.isIntersectionTypeNode(parent):
170
173
  case ts.isUnionTypeNode(parent): break;
174
+ default: break;
171
175
  }
172
176
  parent = parent.parent;
173
177
  }
174
- if (namespace != null) return `${namespace.name.text}.${name}`;
175
- return name;
178
+ const namespace = parent.getSourceFile().statements.find((n) => ts.isNamespaceExportDeclaration(n))?.name.text;
179
+ if (namespace == null) return name;
180
+ if (name.startsWith(`${namespace}.`)) return name;
181
+ return `${namespace}.${name}`;
176
182
  }
177
183
 
178
184
  //#endregion
@@ -221,7 +227,7 @@ function getTypeVariants(types) {
221
227
 
222
228
  //#endregion
223
229
  //#region src/rules/component-hook-factories.ts
224
- const RULE_NAME$64 = "component-hook-factories";
230
+ const RULE_NAME$66 = "component-hook-factories";
225
231
  var component_hook_factories_default = createRule({
226
232
  meta: {
227
233
  type: "problem",
@@ -232,11 +238,11 @@ var component_hook_factories_default = createRule({
232
238
  },
233
239
  schema: []
234
240
  },
235
- name: RULE_NAME$64,
236
- create: create$64,
241
+ name: RULE_NAME$66,
242
+ create: create$66,
237
243
  defaultOptions: []
238
244
  });
239
- function create$64(context) {
245
+ function create$66(context) {
240
246
  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
247
  const fCollector = core.useComponentCollector(context, { hint });
242
248
  const cCollector = core.useComponentCollectorLegacy(context);
@@ -280,7 +286,7 @@ function create$64(context) {
280
286
 
281
287
  //#endregion
282
288
  //#region src/rules/error-boundaries.ts
283
- const RULE_NAME$63 = "error-boundaries";
289
+ const RULE_NAME$65 = "error-boundaries";
284
290
  var error_boundaries_default = createRule({
285
291
  meta: {
286
292
  type: "problem",
@@ -291,11 +297,11 @@ var error_boundaries_default = createRule({
291
297
  },
292
298
  schema: []
293
299
  },
294
- name: RULE_NAME$63,
295
- create: create$63,
300
+ name: RULE_NAME$65,
301
+ create: create$65,
296
302
  defaultOptions: []
297
303
  });
298
- function create$63(context) {
304
+ function create$65(context) {
299
305
  if (!context.sourceCode.text.includes("try")) return {};
300
306
  const { ctx, visitor } = core.useComponentCollector(context);
301
307
  const reported = /* @__PURE__ */ new Set();
@@ -329,7 +335,7 @@ function create$63(context) {
329
335
 
330
336
  //#endregion
331
337
  //#region src/rules/exhaustive-deps.ts
332
- const RULE_NAME$62 = "exhaustive-deps";
338
+ const RULE_NAME$64 = "exhaustive-deps";
333
339
  /**
334
340
  * Built-in hooks that accept dependency arrays.
335
341
  * Maps hook name to the index of the callback argument.
@@ -469,6 +475,23 @@ function findComponentOrHookScope(node) {
469
475
  return null;
470
476
  }
471
477
  /**
478
+ * Check if a variable's definition is contained within a given AST node.
479
+ * Used to exclude callback-local variables from the reactive deps list —
480
+ * a variable declared inside the effect/memo callback is a local, not a dep.
481
+ * @param variable - the variable to check
482
+ * @param node - the node that must NOT contain the variable's definition
483
+ */
484
+ function isDefinedInsideNode(variable, node) {
485
+ for (const def of variable.defs) {
486
+ let current = def.name;
487
+ while (current.parent != null) {
488
+ current = current.parent;
489
+ if (current === node) return true;
490
+ }
491
+ }
492
+ return false;
493
+ }
494
+ /**
472
495
  * Check if a variable is defined within the given function scope (reactive).
473
496
  * @param variable - the variable to check
474
497
  * @param scopeNode - the function scope to check against
@@ -508,11 +531,11 @@ var exhaustive_deps_default = createRule({
508
531
  properties: { additionalHooks: { type: "string" } }
509
532
  }]
510
533
  },
511
- name: RULE_NAME$62,
512
- create: create$62,
534
+ name: RULE_NAME$64,
535
+ create: create$64,
513
536
  defaultOptions: [{}]
514
537
  });
515
- function create$62(context) {
538
+ function create$64(context) {
516
539
  const additionalHooks = context.options[0]?.additionalHooks;
517
540
  const additionalHooksRegex = additionalHooks != null && additionalHooks.length > 0 ? new RegExp(additionalHooks) : null;
518
541
  /** Collected hook calls for later analysis. */
@@ -580,6 +603,7 @@ function create$62(context) {
580
603
  if (variable == null) continue;
581
604
  if (isStableVariable(variable)) continue;
582
605
  if (!isDefinedInScope(variable, componentScope)) continue;
606
+ if (isDefinedInsideNode(variable, callbackNode)) continue;
583
607
  reactiveDeps.add(memberExprText);
584
608
  continue;
585
609
  }
@@ -587,6 +611,7 @@ function create$62(context) {
587
611
  if (variable == null) continue;
588
612
  if (isStableVariable(variable)) continue;
589
613
  if (!isDefinedInScope(variable, componentScope)) continue;
614
+ if (isDefinedInsideNode(variable, callbackNode)) continue;
590
615
  reactiveDeps.add(identifier.name);
591
616
  }
592
617
  return reactiveDeps;
@@ -636,6 +661,32 @@ function create$62(context) {
636
661
  return deps;
637
662
  }
638
663
  /**
664
+ * Check if a reactive dependency is covered by a declared dependency.
665
+ * A declared dep covers a reactive dep if they are equal, or if the
666
+ * declared dep is a prefix ancestor (e.g. `array` covers `array.map`,
667
+ * `obj` covers `obj.a?.toString`).
668
+ * @param reactiveDep
669
+ * @param declaredDeps
670
+ */
671
+ function isCoveredByDeclaredDep(reactiveDep, declaredDeps) {
672
+ if (declaredDeps.has(reactiveDep)) return true;
673
+ for (const declared of declaredDeps) if (reactiveDep.startsWith(`${declared}.`) || reactiveDep.startsWith(`${declared}?.`)) return true;
674
+ return false;
675
+ }
676
+ /**
677
+ * Check if a declared dependency covers at least one reactive dependency.
678
+ * A declared dep is considered necessary if it equals a reactive dep, or if
679
+ * it is a prefix ancestor of any reactive dep (e.g. `array` is necessary
680
+ * when `array.map` is reactive).
681
+ * @param declaredDep
682
+ * @param reactiveDeps
683
+ */
684
+ function declaredDepCoversAny(declaredDep, reactiveDeps) {
685
+ if (reactiveDeps.has(declaredDep)) return true;
686
+ for (const reactive of reactiveDeps) if (reactive.startsWith(`${declaredDep}.`) || reactive.startsWith(`${declaredDep}?.`)) return true;
687
+ return false;
688
+ }
689
+ /**
639
690
  * Generate a fix that produces a corrected dependency array.
640
691
  * Removes unnecessary deps, adds missing deps, and sorts all alphabetically.
641
692
  * @param depsNode - the dependency array node
@@ -660,9 +711,9 @@ function create$62(context) {
660
711
  const reactiveDeps = collectReactiveDeps(callback, componentScope);
661
712
  const declaredDeps = getDeclaredDeps(depsNode);
662
713
  const missingDeps = /* @__PURE__ */ new Set();
663
- for (const dep of reactiveDeps) if (!declaredDeps.has(dep)) missingDeps.add(dep);
714
+ for (const dep of reactiveDeps) if (!isCoveredByDeclaredDep(dep, declaredDeps)) missingDeps.add(dep);
664
715
  const unnecessaryDeps = /* @__PURE__ */ new Set();
665
- for (const dep of declaredDeps) if (!reactiveDeps.has(dep)) unnecessaryDeps.add(dep);
716
+ for (const dep of declaredDeps) if (!declaredDepCoversAny(dep, reactiveDeps)) unnecessaryDeps.add(dep);
666
717
  const hasMissing = missingDeps.size > 0;
667
718
  const hasUnnecessary = unnecessaryDeps.size > 0;
668
719
  if (!hasMissing && !hasUnnecessary) return;
@@ -692,7 +743,7 @@ function create$62(context) {
692
743
  });
693
744
  }
694
745
  }
695
- return {
746
+ return defineRuleListener({
696
747
  CallExpression(node) {
697
748
  if (!isHookWithDeps(node)) return;
698
749
  const hookName = getHookName$1(node);
@@ -719,12 +770,12 @@ function create$62(context) {
719
770
  "Program:exit"() {
720
771
  for (const hookCall of collectedHookCalls) analyzeHookCall(hookCall);
721
772
  }
722
- };
773
+ });
723
774
  }
724
775
 
725
776
  //#endregion
726
777
  //#region src/rules/jsx-dollar.ts
727
- const RULE_NAME$61 = "jsx-dollar";
778
+ const RULE_NAME$63 = "jsx-dollar";
728
779
  var jsx_dollar_default = createRule({
729
780
  meta: {
730
781
  type: "problem",
@@ -737,11 +788,11 @@ var jsx_dollar_default = createRule({
737
788
  },
738
789
  schema: []
739
790
  },
740
- name: RULE_NAME$61,
741
- create: create$61,
791
+ name: RULE_NAME$63,
792
+ create: create$63,
742
793
  defaultOptions: []
743
794
  });
744
- function create$61(context) {
795
+ function create$63(context) {
745
796
  /**
746
797
  * Visitor function for JSXElement and JSXFragment nodes
747
798
  * @param node The JSXElement or JSXFragment node to be checked
@@ -774,15 +825,15 @@ function create$61(context) {
774
825
  });
775
826
  }
776
827
  };
777
- return {
828
+ return defineRuleListener({
778
829
  JSXElement: visitorFunction,
779
830
  JSXFragment: visitorFunction
780
- };
831
+ });
781
832
  }
782
833
 
783
834
  //#endregion
784
835
  //#region src/rules/jsx-key-before-spread.ts
785
- const RULE_NAME$60 = "jsx-key-before-spread";
836
+ const RULE_NAME$62 = "jsx-key-before-spread";
786
837
  var jsx_key_before_spread_default = createRule({
787
838
  meta: {
788
839
  type: "problem",
@@ -790,17 +841,17 @@ var jsx_key_before_spread_default = createRule({
790
841
  messages: { default: "The 'key' prop must be placed before any spread props when using the new JSX transform." },
791
842
  schema: []
792
843
  },
793
- name: RULE_NAME$60,
794
- create: create$60,
844
+ name: RULE_NAME$62,
845
+ create: create$62,
795
846
  defaultOptions: []
796
847
  });
797
- function create$60(context) {
848
+ function create$62(context) {
798
849
  const { jsx } = {
799
850
  ...core.getJsxConfigFromContext(context),
800
851
  ...core.getJsxConfigFromAnnotation(context)
801
852
  };
802
853
  if (jsx !== core.JsxEmit.ReactJSX && jsx !== core.JsxEmit.ReactJSXDev) return {};
803
- return { JSXOpeningElement(node) {
854
+ return defineRuleListener({ JSXOpeningElement(node) {
804
855
  let firstSpreadPropIndex = null;
805
856
  for (const [index, prop] of node.attributes.entries()) {
806
857
  if (prop.type === AST_NODE_TYPES.JSXSpreadAttribute) {
@@ -813,12 +864,12 @@ function create$60(context) {
813
864
  node: prop
814
865
  });
815
866
  }
816
- } };
867
+ } });
817
868
  }
818
869
 
819
870
  //#endregion
820
871
  //#region src/rules/jsx-no-comment-textnodes.ts
821
- const RULE_NAME$59 = "jsx-no-comment-textnodes";
872
+ const RULE_NAME$61 = "jsx-no-comment-textnodes";
822
873
  var jsx_no_comment_textnodes_default = createRule({
823
874
  meta: {
824
875
  type: "problem",
@@ -826,11 +877,11 @@ var jsx_no_comment_textnodes_default = createRule({
826
877
  messages: { default: "Possible misused comment in text node. Comments inside children section of tag should be placed inside braces." },
827
878
  schema: []
828
879
  },
829
- name: RULE_NAME$59,
830
- create: create$59,
880
+ name: RULE_NAME$61,
881
+ create: create$61,
831
882
  defaultOptions: []
832
883
  });
833
- function create$59(context) {
884
+ function create$61(context) {
834
885
  function hasCommentLike(node) {
835
886
  if (ast.isOneOf([AST_NODE_TYPES.JSXAttribute, AST_NODE_TYPES.JSXExpressionContainer])(node.parent)) return false;
836
887
  return /^\s*\/(?:\/|\*)/mu.test(context.sourceCode.getText(node));
@@ -843,15 +894,15 @@ function create$59(context) {
843
894
  node
844
895
  });
845
896
  };
846
- return {
897
+ return defineRuleListener({
847
898
  JSXText: visitorFunction,
848
899
  Literal: visitorFunction
849
- };
900
+ });
850
901
  }
851
902
 
852
903
  //#endregion
853
904
  //#region src/rules/jsx-no-duplicate-props.ts
854
- const RULE_NAME$58 = "jsx-no-duplicate-props";
905
+ const RULE_NAME$60 = "jsx-no-duplicate-props";
855
906
  var jsx_no_duplicate_props_default = createRule({
856
907
  meta: {
857
908
  type: "problem",
@@ -859,12 +910,12 @@ var jsx_no_duplicate_props_default = createRule({
859
910
  messages: { default: "This JSX property is assigned multiple times." },
860
911
  schema: []
861
912
  },
862
- name: RULE_NAME$58,
863
- create: create$58,
913
+ name: RULE_NAME$60,
914
+ create: create$60,
864
915
  defaultOptions: []
865
916
  });
866
- function create$58(context) {
867
- return { JSXOpeningElement(node) {
917
+ function create$60(context) {
918
+ return defineRuleListener({ JSXOpeningElement(node) {
868
919
  const props = [];
869
920
  for (const attr of node.attributes) {
870
921
  if (attr.type === AST_NODE_TYPES.JSXSpreadAttribute) continue;
@@ -879,43 +930,12 @@ function create$58(context) {
879
930
  node: attr
880
931
  });
881
932
  }
882
- } };
883
- }
884
-
885
- //#endregion
886
- //#region src/rules/jsx-no-iife.ts
887
- const RULE_NAME$57 = "jsx-no-iife";
888
- var jsx_no_iife_default = createRule({
889
- meta: {
890
- type: "problem",
891
- docs: { description: "Disallows immediately-invoked function expressions in JSX." },
892
- messages: { default: "Avoid using immediately-invoked function expressions in JSX." },
893
- schema: []
894
- },
895
- name: RULE_NAME$57,
896
- create: create$57,
897
- defaultOptions: []
898
- });
899
- function create$57(context) {
900
- return {
901
- "JSXElement :function"(node) {
902
- if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) context.report({
903
- messageId: "default",
904
- node: node.parent
905
- });
906
- },
907
- "JSXFragment :function"(node) {
908
- if (node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node) context.report({
909
- messageId: "default",
910
- node: node.parent
911
- });
912
- }
913
- };
933
+ } });
914
934
  }
915
935
 
916
936
  //#endregion
917
937
  //#region src/rules/jsx-no-undef.ts
918
- const RULE_NAME$56 = "jsx-no-undef";
938
+ const RULE_NAME$59 = "jsx-no-undef";
919
939
  var jsx_no_undef_default = createRule({
920
940
  meta: {
921
941
  type: "problem",
@@ -923,12 +943,12 @@ var jsx_no_undef_default = createRule({
923
943
  messages: { default: "JSX variable '{{name}}' is not defined." },
924
944
  schema: []
925
945
  },
926
- name: RULE_NAME$56,
927
- create: create$56,
946
+ name: RULE_NAME$59,
947
+ create: create$59,
928
948
  defaultOptions: []
929
949
  });
930
- function create$56(context) {
931
- return { JSXOpeningElement(node) {
950
+ function create$59(context) {
951
+ return defineRuleListener({ JSXOpeningElement(node) {
932
952
  const name = match(node.name).with({ type: AST_NODE_TYPES.JSXIdentifier }, (n) => n.name).with({
933
953
  type: AST_NODE_TYPES.JSXMemberExpression,
934
954
  object: { type: AST_NODE_TYPES.JSXIdentifier }
@@ -941,14 +961,14 @@ function create$56(context) {
941
961
  node,
942
962
  data: { name }
943
963
  });
944
- } };
964
+ } });
945
965
  }
946
966
 
947
967
  //#endregion
948
968
  //#region src/rules/jsx-shorthand-boolean.ts
949
- const RULE_NAME$55 = "jsx-shorthand-boolean";
950
- const defaultOptions$3 = [1];
951
- const schema$3 = [{
969
+ const RULE_NAME$58 = "jsx-shorthand-boolean";
970
+ const defaultOptions$4 = [1];
971
+ const schema$4 = [{
952
972
  type: "integer",
953
973
  enum: [-1, 1]
954
974
  }];
@@ -958,15 +978,15 @@ var jsx_shorthand_boolean_default = createRule({
958
978
  docs: { description: "Enforces shorthand syntax for boolean props." },
959
979
  fixable: "code",
960
980
  messages: { default: "{{message}}" },
961
- schema: schema$3
981
+ schema: schema$4
962
982
  },
963
- name: RULE_NAME$55,
964
- create: create$55,
965
- defaultOptions: defaultOptions$3
983
+ name: RULE_NAME$58,
984
+ create: create$58,
985
+ defaultOptions: defaultOptions$4
966
986
  });
967
- function create$55(context) {
968
- const policy = context.options[0] ?? defaultOptions$3[0];
969
- return { JSXAttribute(node) {
987
+ function create$58(context) {
988
+ const policy = context.options[0] ?? defaultOptions$4[0];
989
+ return defineRuleListener({ JSXAttribute(node) {
970
990
  const { value } = node;
971
991
  const propName = core.getJsxAttributeName(context, node);
972
992
  switch (true) {
@@ -978,7 +998,7 @@ function create$55(context) {
978
998
  fix: (fixer) => fixer.removeRange([node.name.range[1], value.range[1]])
979
999
  });
980
1000
  break;
981
- case policy === -1 && value === null:
1001
+ case policy === -1 && value == null:
982
1002
  context.report({
983
1003
  messageId: "default",
984
1004
  node: node.value ?? node,
@@ -987,14 +1007,14 @@ function create$55(context) {
987
1007
  });
988
1008
  break;
989
1009
  }
990
- } };
1010
+ } });
991
1011
  }
992
1012
 
993
1013
  //#endregion
994
1014
  //#region src/rules/jsx-shorthand-fragment.ts
995
- const RULE_NAME$54 = "jsx-shorthand-fragment";
996
- const defaultOptions$2 = [1];
997
- const schema$2 = [{
1015
+ const RULE_NAME$57 = "jsx-shorthand-fragment";
1016
+ const defaultOptions$3 = [1];
1017
+ const schema$3 = [{
998
1018
  type: "integer",
999
1019
  enum: [-1, 1]
1000
1020
  }];
@@ -1004,20 +1024,20 @@ var jsx_shorthand_fragment_default = createRule({
1004
1024
  docs: { description: "Enforces shorthand syntax for fragment elements." },
1005
1025
  fixable: "code",
1006
1026
  messages: { default: "{{message}}" },
1007
- schema: schema$2
1027
+ schema: schema$3
1008
1028
  },
1009
- name: RULE_NAME$54,
1010
- create: create$54,
1011
- defaultOptions: defaultOptions$2
1029
+ name: RULE_NAME$57,
1030
+ create: create$57,
1031
+ defaultOptions: defaultOptions$3
1012
1032
  });
1013
- function create$54(context) {
1014
- const policy = context.options[0] ?? defaultOptions$2[0];
1033
+ function create$57(context) {
1034
+ const policy = context.options[0] ?? defaultOptions$3[0];
1015
1035
  const jsxConfig = {
1016
1036
  ...core.getJsxConfigFromContext(context),
1017
1037
  ...core.getJsxConfigFromAnnotation(context)
1018
1038
  };
1019
1039
  const { jsxFragmentFactory } = jsxConfig;
1020
- return match(policy).with(1, () => ({ JSXElement(node) {
1040
+ return match(policy).with(1, () => defineRuleListener({ JSXElement(node) {
1021
1041
  if (!core.isJsxFragmentElement(context, node, jsxConfig)) return;
1022
1042
  if (node.openingElement.attributes.length > 0) return;
1023
1043
  context.report({
@@ -1030,7 +1050,7 @@ function create$54(context) {
1030
1050
  return [fixer.replaceTextRange([openingElement.range[0], openingElement.range[1]], "<>"), fixer.replaceTextRange([closingElement.range[0], closingElement.range[1]], "</>")];
1031
1051
  }
1032
1052
  });
1033
- } })).with(-1, () => ({ JSXFragment(node) {
1053
+ } })).with(-1, () => defineRuleListener({ JSXFragment(node) {
1034
1054
  context.report({
1035
1055
  messageId: "default",
1036
1056
  node,
@@ -1045,7 +1065,7 @@ function create$54(context) {
1045
1065
 
1046
1066
  //#endregion
1047
1067
  //#region src/rules/jsx-uses-react.ts
1048
- const RULE_NAME$53 = "jsx-uses-react";
1068
+ const RULE_NAME$56 = "jsx-uses-react";
1049
1069
  var jsx_uses_react_default = createRule({
1050
1070
  meta: {
1051
1071
  type: "problem",
@@ -1053,11 +1073,11 @@ var jsx_uses_react_default = createRule({
1053
1073
  messages: { default: "Marked {{name}} as used." },
1054
1074
  schema: []
1055
1075
  },
1056
- name: RULE_NAME$53,
1057
- create: create$53,
1076
+ name: RULE_NAME$56,
1077
+ create: create$56,
1058
1078
  defaultOptions: []
1059
1079
  });
1060
- function create$53(context) {
1080
+ function create$56(context) {
1061
1081
  const { jsx, jsxFactory, jsxFragmentFactory } = {
1062
1082
  ...core.getJsxConfigFromContext(context),
1063
1083
  ...core.getJsxConfigFromAnnotation(context)
@@ -1071,11 +1091,11 @@ function create$53(context) {
1071
1091
  context.sourceCode.markVariableAsUsed(jsxFragmentFactory, node);
1072
1092
  debugReport(context, node, jsxFragmentFactory);
1073
1093
  }
1074
- return {
1094
+ return defineRuleListener({
1075
1095
  JSXFragment: handleJsxFragment,
1076
1096
  JSXOpeningElement: handleJsxElement,
1077
1097
  JSXOpeningFragment: handleJsxElement
1078
- };
1098
+ });
1079
1099
  }
1080
1100
  function debugReport(context, node, name) {
1081
1101
  if (process.env["ESLINT_REACT_DEBUG"] !== "1") return;
@@ -1088,7 +1108,7 @@ function debugReport(context, node, name) {
1088
1108
 
1089
1109
  //#endregion
1090
1110
  //#region src/rules/jsx-uses-vars.ts
1091
- const RULE_NAME$52 = "jsx-uses-vars";
1111
+ const RULE_NAME$55 = "jsx-uses-vars";
1092
1112
  var jsx_uses_vars_default = createRule({
1093
1113
  meta: {
1094
1114
  type: "problem",
@@ -1096,12 +1116,12 @@ var jsx_uses_vars_default = createRule({
1096
1116
  messages: { default: "An identifier in JSX is marked as used." },
1097
1117
  schema: []
1098
1118
  },
1099
- name: RULE_NAME$52,
1100
- create: create$52,
1119
+ name: RULE_NAME$55,
1120
+ create: create$55,
1101
1121
  defaultOptions: []
1102
1122
  });
1103
- function create$52(context) {
1104
- return { JSXOpeningElement(node) {
1123
+ function create$55(context) {
1124
+ return defineRuleListener({ JSXOpeningElement(node) {
1105
1125
  switch (node.name.type) {
1106
1126
  case AST_NODE_TYPES.JSXIdentifier:
1107
1127
  if (/^[a-z]/u.test(node.name.name)) return;
@@ -1113,12 +1133,12 @@ function create$52(context) {
1113
1133
  break;
1114
1134
  }
1115
1135
  }
1116
- } };
1136
+ } });
1117
1137
  }
1118
1138
 
1119
1139
  //#endregion
1120
1140
  //#region src/rules/no-access-state-in-setstate.ts
1121
- const RULE_NAME$51 = "no-access-state-in-setstate";
1141
+ const RULE_NAME$54 = "no-access-state-in-setstate";
1122
1142
  function isKeyLiteral$2(node, key) {
1123
1143
  return match(key).with({ type: AST_NODE_TYPES.Literal }, constTrue).with({
1124
1144
  type: AST_NODE_TYPES.TemplateLiteral,
@@ -1132,16 +1152,16 @@ var no_access_state_in_setstate_default = createRule({
1132
1152
  messages: { default: "Do not access 'this.state' within 'setState'. Use the update function instead." },
1133
1153
  schema: []
1134
1154
  },
1135
- name: RULE_NAME$51,
1136
- create: create$51,
1155
+ name: RULE_NAME$54,
1156
+ create: create$54,
1137
1157
  defaultOptions: []
1138
1158
  });
1139
- function create$51(context) {
1159
+ function create$54(context) {
1140
1160
  if (!context.sourceCode.text.includes("setState")) return {};
1141
1161
  const classStack = [];
1142
1162
  const methodStack = [];
1143
1163
  const setStateStack = [];
1144
- return {
1164
+ return defineRuleListener({
1145
1165
  CallExpression(node) {
1146
1166
  if (!core.isThisSetState(node)) return;
1147
1167
  setStateStack.push([node, false]);
@@ -1202,12 +1222,12 @@ function create$51(context) {
1202
1222
  node
1203
1223
  });
1204
1224
  }
1205
- };
1225
+ });
1206
1226
  }
1207
1227
 
1208
1228
  //#endregion
1209
1229
  //#region src/rules/no-array-index-key.ts
1210
- const RULE_NAME$50 = "no-array-index-key";
1230
+ const RULE_NAME$53 = "no-array-index-key";
1211
1231
  const REACT_CHILDREN_METHOD = ["forEach", "map"];
1212
1232
  function getIndexParamPosition(methodName) {
1213
1233
  switch (methodName) {
@@ -1266,11 +1286,11 @@ var no_array_index_key_default = createRule({
1266
1286
  messages: { default: "Do not use item index in the array as its key." },
1267
1287
  schema: []
1268
1288
  },
1269
- name: RULE_NAME$50,
1270
- create: create$50,
1289
+ name: RULE_NAME$53,
1290
+ create: create$53,
1271
1291
  defaultOptions: []
1272
1292
  });
1273
- function create$50(context) {
1293
+ function create$53(context) {
1274
1294
  const indexParamNames = [];
1275
1295
  function isArrayIndex(node) {
1276
1296
  return node.type === AST_NODE_TYPES.Identifier && indexParamNames.some((name) => name != null && name === node.name);
@@ -1309,7 +1329,7 @@ function create$50(context) {
1309
1329
  }
1310
1330
  return [];
1311
1331
  }
1312
- return {
1332
+ return defineRuleListener({
1313
1333
  CallExpression(node) {
1314
1334
  indexParamNames.push(getMapIndexParamName(context, node));
1315
1335
  if (node.arguments.length === 0) return;
@@ -1331,12 +1351,12 @@ function create$50(context) {
1331
1351
  if (node.value?.type !== AST_NODE_TYPES.JSXExpressionContainer) return;
1332
1352
  for (const descriptor of getReportDescriptors(node.value.expression)) report(context)(descriptor);
1333
1353
  }
1334
- };
1354
+ });
1335
1355
  }
1336
1356
 
1337
1357
  //#endregion
1338
1358
  //#region src/rules/no-children-count.ts
1339
- const RULE_NAME$49 = "no-children-count";
1359
+ const RULE_NAME$52 = "no-children-count";
1340
1360
  var no_children_count_default = createRule({
1341
1361
  meta: {
1342
1362
  type: "problem",
@@ -1344,22 +1364,22 @@ var no_children_count_default = createRule({
1344
1364
  messages: { default: "Using 'Children.count' is uncommon and can lead to fragile code. Use alternatives instead." },
1345
1365
  schema: []
1346
1366
  },
1347
- name: RULE_NAME$49,
1348
- create: create$49,
1367
+ name: RULE_NAME$52,
1368
+ create: create$52,
1349
1369
  defaultOptions: []
1350
1370
  });
1351
- function create$49(context) {
1352
- return { MemberExpression(node) {
1371
+ function create$52(context) {
1372
+ return defineRuleListener({ MemberExpression(node) {
1353
1373
  if (core.isChildrenCount(context, node)) context.report({
1354
1374
  messageId: "default",
1355
1375
  node: node.property
1356
1376
  });
1357
- } };
1377
+ } });
1358
1378
  }
1359
1379
 
1360
1380
  //#endregion
1361
1381
  //#region src/rules/no-children-for-each.ts
1362
- const RULE_NAME$48 = "no-children-for-each";
1382
+ const RULE_NAME$51 = "no-children-for-each";
1363
1383
  var no_children_for_each_default = createRule({
1364
1384
  meta: {
1365
1385
  type: "problem",
@@ -1367,22 +1387,22 @@ var no_children_for_each_default = createRule({
1367
1387
  messages: { default: "Using 'Children.forEach' is uncommon and can lead to fragile code. Use alternatives instead." },
1368
1388
  schema: []
1369
1389
  },
1370
- name: RULE_NAME$48,
1371
- create: create$48,
1390
+ name: RULE_NAME$51,
1391
+ create: create$51,
1372
1392
  defaultOptions: []
1373
1393
  });
1374
- function create$48(context) {
1375
- return { MemberExpression(node) {
1394
+ function create$51(context) {
1395
+ return defineRuleListener({ MemberExpression(node) {
1376
1396
  if (core.isChildrenForEach(context, node)) context.report({
1377
1397
  messageId: "default",
1378
1398
  node: node.property
1379
1399
  });
1380
- } };
1400
+ } });
1381
1401
  }
1382
1402
 
1383
1403
  //#endregion
1384
1404
  //#region src/rules/no-children-map.ts
1385
- const RULE_NAME$47 = "no-children-map";
1405
+ const RULE_NAME$50 = "no-children-map";
1386
1406
  var no_children_map_default = createRule({
1387
1407
  meta: {
1388
1408
  type: "problem",
@@ -1390,22 +1410,22 @@ var no_children_map_default = createRule({
1390
1410
  messages: { default: "Using 'Children.map' is uncommon and can lead to fragile code. Use alternatives instead." },
1391
1411
  schema: []
1392
1412
  },
1393
- name: RULE_NAME$47,
1394
- create: create$47,
1413
+ name: RULE_NAME$50,
1414
+ create: create$50,
1395
1415
  defaultOptions: []
1396
1416
  });
1397
- function create$47(context) {
1398
- return { MemberExpression(node) {
1417
+ function create$50(context) {
1418
+ return defineRuleListener({ MemberExpression(node) {
1399
1419
  if (core.isChildrenMap(context, node)) context.report({
1400
1420
  messageId: "default",
1401
1421
  node: node.property
1402
1422
  });
1403
- } };
1423
+ } });
1404
1424
  }
1405
1425
 
1406
1426
  //#endregion
1407
1427
  //#region src/rules/no-children-only.ts
1408
- const RULE_NAME$46 = "no-children-only";
1428
+ const RULE_NAME$49 = "no-children-only";
1409
1429
  var no_children_only_default = createRule({
1410
1430
  meta: {
1411
1431
  type: "problem",
@@ -1413,22 +1433,22 @@ var no_children_only_default = createRule({
1413
1433
  messages: { default: "Using 'Children.only' is uncommon and can lead to fragile code. Use alternatives instead." },
1414
1434
  schema: []
1415
1435
  },
1416
- name: RULE_NAME$46,
1417
- create: create$46,
1436
+ name: RULE_NAME$49,
1437
+ create: create$49,
1418
1438
  defaultOptions: []
1419
1439
  });
1420
- function create$46(context) {
1421
- return { MemberExpression(node) {
1440
+ function create$49(context) {
1441
+ return defineRuleListener({ MemberExpression(node) {
1422
1442
  if (core.isChildrenOnly(context, node)) context.report({
1423
1443
  messageId: "default",
1424
1444
  node: node.property
1425
1445
  });
1426
- } };
1446
+ } });
1427
1447
  }
1428
1448
 
1429
1449
  //#endregion
1430
1450
  //#region src/rules/no-children-prop.ts
1431
- const RULE_NAME$45 = "no-children-prop";
1451
+ const RULE_NAME$48 = "no-children-prop";
1432
1452
  var no_children_prop_default = createRule({
1433
1453
  meta: {
1434
1454
  type: "problem",
@@ -1436,23 +1456,23 @@ var no_children_prop_default = createRule({
1436
1456
  messages: { default: "Do not pass 'children' as props." },
1437
1457
  schema: []
1438
1458
  },
1439
- name: RULE_NAME$45,
1440
- create: create$45,
1459
+ name: RULE_NAME$48,
1460
+ create: create$48,
1441
1461
  defaultOptions: []
1442
1462
  });
1443
- function create$45(context) {
1444
- return { JSXElement(node) {
1463
+ function create$48(context) {
1464
+ return defineRuleListener({ JSXElement(node) {
1445
1465
  const childrenProp = core.getJsxAttribute(context, node)("children");
1446
1466
  if (childrenProp != null) context.report({
1447
1467
  messageId: "default",
1448
1468
  node: childrenProp
1449
1469
  });
1450
- } };
1470
+ } });
1451
1471
  }
1452
1472
 
1453
1473
  //#endregion
1454
1474
  //#region src/rules/no-children-to-array.ts
1455
- const RULE_NAME$44 = "no-children-to-array";
1475
+ const RULE_NAME$47 = "no-children-to-array";
1456
1476
  var no_children_to_array_default = createRule({
1457
1477
  meta: {
1458
1478
  type: "problem",
@@ -1460,22 +1480,22 @@ var no_children_to_array_default = createRule({
1460
1480
  messages: { default: "Using 'Children.toArray' is uncommon and can lead to fragile code. Use alternatives instead." },
1461
1481
  schema: []
1462
1482
  },
1463
- name: RULE_NAME$44,
1464
- create: create$44,
1483
+ name: RULE_NAME$47,
1484
+ create: create$47,
1465
1485
  defaultOptions: []
1466
1486
  });
1467
- function create$44(context) {
1468
- return { MemberExpression(node) {
1487
+ function create$47(context) {
1488
+ return defineRuleListener({ MemberExpression(node) {
1469
1489
  if (core.isChildrenToArray(context, node)) context.report({
1470
1490
  messageId: "default",
1471
1491
  node: node.property
1472
1492
  });
1473
- } };
1493
+ } });
1474
1494
  }
1475
1495
 
1476
1496
  //#endregion
1477
1497
  //#region src/rules/no-class-component.ts
1478
- const RULE_NAME$43 = "no-class-component";
1498
+ const RULE_NAME$46 = "no-class-component";
1479
1499
  var no_class_component_default = createRule({
1480
1500
  meta: {
1481
1501
  type: "problem",
@@ -1483,11 +1503,11 @@ var no_class_component_default = createRule({
1483
1503
  messages: { default: "Avoid using class components. Use function components instead." },
1484
1504
  schema: []
1485
1505
  },
1486
- name: RULE_NAME$43,
1487
- create: create$43,
1506
+ name: RULE_NAME$46,
1507
+ create: create$46,
1488
1508
  defaultOptions: []
1489
1509
  });
1490
- function create$43(context) {
1510
+ function create$46(context) {
1491
1511
  if (!context.sourceCode.text.includes("Component")) return {};
1492
1512
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
1493
1513
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1504,7 +1524,7 @@ function create$43(context) {
1504
1524
 
1505
1525
  //#endregion
1506
1526
  //#region src/rules/no-clone-element.ts
1507
- const RULE_NAME$42 = "no-clone-element";
1527
+ const RULE_NAME$45 = "no-clone-element";
1508
1528
  var no_clone_element_default = createRule({
1509
1529
  meta: {
1510
1530
  type: "problem",
@@ -1512,22 +1532,22 @@ var no_clone_element_default = createRule({
1512
1532
  messages: { default: "Using 'cloneElement' is uncommon and can lead to fragile code. Use alternatives instead." },
1513
1533
  schema: []
1514
1534
  },
1515
- name: RULE_NAME$42,
1516
- create: create$42,
1535
+ name: RULE_NAME$45,
1536
+ create: create$45,
1517
1537
  defaultOptions: []
1518
1538
  });
1519
- function create$42(context) {
1520
- return { CallExpression(node) {
1539
+ function create$45(context) {
1540
+ return defineRuleListener({ CallExpression(node) {
1521
1541
  if (core.isCloneElementCall(context, node)) context.report({
1522
1542
  messageId: "default",
1523
1543
  node
1524
1544
  });
1525
- } };
1545
+ } });
1526
1546
  }
1527
1547
 
1528
1548
  //#endregion
1529
1549
  //#region src/rules/no-component-will-mount.ts
1530
- const RULE_NAME$41 = "no-component-will-mount";
1550
+ const RULE_NAME$44 = "no-component-will-mount";
1531
1551
  var no_component_will_mount_default = createRule({
1532
1552
  meta: {
1533
1553
  type: "problem",
@@ -1536,11 +1556,11 @@ var no_component_will_mount_default = createRule({
1536
1556
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillMount' instead." },
1537
1557
  schema: []
1538
1558
  },
1539
- name: RULE_NAME$41,
1540
- create: create$41,
1559
+ name: RULE_NAME$44,
1560
+ create: create$44,
1541
1561
  defaultOptions: []
1542
1562
  });
1543
- function create$41(context) {
1563
+ function create$44(context) {
1544
1564
  if (!context.sourceCode.text.includes("componentWillMount")) return {};
1545
1565
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
1546
1566
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1560,7 +1580,7 @@ function create$41(context) {
1560
1580
 
1561
1581
  //#endregion
1562
1582
  //#region src/rules/no-component-will-receive-props.ts
1563
- const RULE_NAME$40 = "no-component-will-receive-props";
1583
+ const RULE_NAME$43 = "no-component-will-receive-props";
1564
1584
  var no_component_will_receive_props_default = createRule({
1565
1585
  meta: {
1566
1586
  type: "problem",
@@ -1569,11 +1589,11 @@ var no_component_will_receive_props_default = createRule({
1569
1589
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillReceiveProps' instead." },
1570
1590
  schema: []
1571
1591
  },
1572
- name: RULE_NAME$40,
1573
- create: create$40,
1592
+ name: RULE_NAME$43,
1593
+ create: create$43,
1574
1594
  defaultOptions: []
1575
1595
  });
1576
- function create$40(context) {
1596
+ function create$43(context) {
1577
1597
  if (!context.sourceCode.text.includes("componentWillReceiveProps")) return {};
1578
1598
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
1579
1599
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1593,7 +1613,7 @@ function create$40(context) {
1593
1613
 
1594
1614
  //#endregion
1595
1615
  //#region src/rules/no-component-will-update.ts
1596
- const RULE_NAME$39 = "no-component-will-update";
1616
+ const RULE_NAME$42 = "no-component-will-update";
1597
1617
  var no_component_will_update_default = createRule({
1598
1618
  meta: {
1599
1619
  type: "problem",
@@ -1602,11 +1622,11 @@ var no_component_will_update_default = createRule({
1602
1622
  messages: { default: "[Deprecated] Use 'UNSAFE_componentWillUpdate' instead." },
1603
1623
  schema: []
1604
1624
  },
1605
- name: RULE_NAME$39,
1606
- create: create$39,
1625
+ name: RULE_NAME$42,
1626
+ create: create$42,
1607
1627
  defaultOptions: []
1608
1628
  });
1609
- function create$39(context) {
1629
+ function create$42(context) {
1610
1630
  if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
1611
1631
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
1612
1632
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -1626,7 +1646,7 @@ function create$39(context) {
1626
1646
 
1627
1647
  //#endregion
1628
1648
  //#region src/rules/no-context-provider.ts
1629
- const RULE_NAME$38 = "no-context-provider";
1649
+ const RULE_NAME$41 = "no-context-provider";
1630
1650
  var no_context_provider_default = createRule({
1631
1651
  meta: {
1632
1652
  type: "problem",
@@ -1635,15 +1655,15 @@ var no_context_provider_default = createRule({
1635
1655
  messages: { default: "In React 19, you can render '<Context>' as a provider instead of '<Context.Provider>'." },
1636
1656
  schema: []
1637
1657
  },
1638
- name: RULE_NAME$38,
1639
- create: create$38,
1658
+ name: RULE_NAME$41,
1659
+ create: create$41,
1640
1660
  defaultOptions: []
1641
1661
  });
1642
- function create$38(context) {
1662
+ function create$41(context) {
1643
1663
  if (!context.sourceCode.text.includes("Provider")) return {};
1644
1664
  const { version } = getSettingsFromContext(context);
1645
1665
  if (compare(version, "19.0.0", "<")) return {};
1646
- return { JSXElement(node) {
1666
+ return defineRuleListener({ JSXElement(node) {
1647
1667
  const parts = core.getJsxElementType(context, node).split(".");
1648
1668
  const selfName = parts.pop();
1649
1669
  const contextFullName = parts.join(".");
@@ -1661,12 +1681,12 @@ function create$38(context) {
1661
1681
  return [fixer.replaceText(openingElement.name, contextFullName), fixer.replaceText(closingElement.name, contextFullName)];
1662
1682
  }
1663
1683
  });
1664
- } };
1684
+ } });
1665
1685
  }
1666
1686
 
1667
1687
  //#endregion
1668
1688
  //#region src/rules/no-create-ref.ts
1669
- const RULE_NAME$37 = "no-create-ref";
1689
+ const RULE_NAME$40 = "no-create-ref";
1670
1690
  var no_create_ref_default = createRule({
1671
1691
  meta: {
1672
1692
  type: "problem",
@@ -1674,22 +1694,22 @@ var no_create_ref_default = createRule({
1674
1694
  messages: { default: "[Deprecated] Use 'useRef' instead." },
1675
1695
  schema: []
1676
1696
  },
1677
- name: RULE_NAME$37,
1678
- create: create$37,
1697
+ name: RULE_NAME$40,
1698
+ create: create$40,
1679
1699
  defaultOptions: []
1680
1700
  });
1681
- function create$37(context) {
1682
- return { CallExpression(node) {
1701
+ function create$40(context) {
1702
+ return defineRuleListener({ CallExpression(node) {
1683
1703
  if (core.isCreateRefCall(context, node) && ast.findParentNode(node, core.isClassComponent) == null) context.report({
1684
1704
  messageId: "default",
1685
1705
  node
1686
1706
  });
1687
- } };
1707
+ } });
1688
1708
  }
1689
1709
 
1690
1710
  //#endregion
1691
1711
  //#region src/rules/no-direct-mutation-state.ts
1692
- const RULE_NAME$36 = "no-direct-mutation-state";
1712
+ const RULE_NAME$39 = "no-direct-mutation-state";
1693
1713
  function isConstructorFunction(node) {
1694
1714
  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";
1695
1715
  }
@@ -1700,12 +1720,12 @@ var no_direct_mutation_state_default = createRule({
1700
1720
  messages: { default: "Do not mutate state directly. Use 'setState()' instead." },
1701
1721
  schema: []
1702
1722
  },
1703
- name: RULE_NAME$36,
1704
- create: create$36,
1723
+ name: RULE_NAME$39,
1724
+ create: create$39,
1705
1725
  defaultOptions: []
1706
1726
  });
1707
- function create$36(context) {
1708
- return { AssignmentExpression(node) {
1727
+ function create$39(context) {
1728
+ return defineRuleListener({ AssignmentExpression(node) {
1709
1729
  if (!core.isAssignmentToThisState(node)) return;
1710
1730
  const parentClass = ast.findParentNode(node, ast.isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression]));
1711
1731
  if (parentClass == null) return;
@@ -1713,12 +1733,12 @@ function create$36(context) {
1713
1733
  messageId: "default",
1714
1734
  node
1715
1735
  });
1716
- } };
1736
+ } });
1717
1737
  }
1718
1738
 
1719
1739
  //#endregion
1720
1740
  //#region src/rules/no-duplicate-key.ts
1721
- const RULE_NAME$35 = "no-duplicate-key";
1741
+ const RULE_NAME$38 = "no-duplicate-key";
1722
1742
  var no_duplicate_key_default = createRule({
1723
1743
  meta: {
1724
1744
  type: "problem",
@@ -1726,11 +1746,11 @@ var no_duplicate_key_default = createRule({
1726
1746
  messages: { default: "The 'key' prop must be unique to its sibling elements." },
1727
1747
  schema: []
1728
1748
  },
1729
- name: RULE_NAME$35,
1730
- create: create$35,
1749
+ name: RULE_NAME$38,
1750
+ create: create$38,
1731
1751
  defaultOptions: []
1732
1752
  });
1733
- function create$35(context) {
1753
+ function create$38(context) {
1734
1754
  if (!context.sourceCode.text.includes("key=")) return {};
1735
1755
  const keyedEntries = /* @__PURE__ */ new Map();
1736
1756
  function isKeyValueEqual(a, b) {
@@ -1739,7 +1759,7 @@ function create$35(context) {
1739
1759
  if (aValue == null || bValue == null) return false;
1740
1760
  return ast.isNodeEqual(aValue, bValue);
1741
1761
  }
1742
- return {
1762
+ return defineRuleListener({
1743
1763
  "JSXAttribute[name.name='key']"(node) {
1744
1764
  const jsxElement = node.parent.parent;
1745
1765
  switch (jsxElement.parent.type) {
@@ -1780,12 +1800,12 @@ function create$35(context) {
1780
1800
  });
1781
1801
  }
1782
1802
  }
1783
- };
1803
+ });
1784
1804
  }
1785
1805
 
1786
1806
  //#endregion
1787
1807
  //#region src/rules/no-forward-ref.ts
1788
- const RULE_NAME$34 = "no-forward-ref";
1808
+ const RULE_NAME$37 = "no-forward-ref";
1789
1809
  var no_forward_ref_default = createRule({
1790
1810
  meta: {
1791
1811
  type: "problem",
@@ -1794,15 +1814,15 @@ var no_forward_ref_default = createRule({
1794
1814
  messages: { default: "In React 19, 'forwardRef' is no longer necessary. Pass 'ref' as a prop instead." },
1795
1815
  schema: []
1796
1816
  },
1797
- name: RULE_NAME$34,
1798
- create: create$34,
1817
+ name: RULE_NAME$37,
1818
+ create: create$37,
1799
1819
  defaultOptions: []
1800
1820
  });
1801
- function create$34(context) {
1821
+ function create$37(context) {
1802
1822
  if (!context.sourceCode.text.includes("forwardRef")) return {};
1803
1823
  const { version } = getSettingsFromContext(context);
1804
1824
  if (compare(version, "19.0.0", "<")) return {};
1805
- return { CallExpression(node) {
1825
+ return defineRuleListener({ CallExpression(node) {
1806
1826
  if (!core.isForwardRefCall(context, node)) return;
1807
1827
  const id = ast.getFunctionId(node);
1808
1828
  const fix = canFix(context, node) ? getFix(context, node) : null;
@@ -1811,7 +1831,7 @@ function create$34(context) {
1811
1831
  node: id ?? node,
1812
1832
  fix
1813
1833
  });
1814
- } };
1834
+ } });
1815
1835
  }
1816
1836
  /**
1817
1837
  * Determine whether the given CallExpression can be safely auto-fixed by replacing
@@ -1893,7 +1913,7 @@ function getComponentPropsFixes(context, fixer, node, typeArguments) {
1893
1913
 
1894
1914
  //#endregion
1895
1915
  //#region src/rules/no-implicit-key.ts
1896
- const RULE_NAME$33 = "no-implicit-key";
1916
+ const RULE_NAME$36 = "no-implicit-key";
1897
1917
  var no_implicit_key_default = createRule({
1898
1918
  meta: {
1899
1919
  type: "problem",
@@ -1901,14 +1921,14 @@ var no_implicit_key_default = createRule({
1901
1921
  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}'." },
1902
1922
  schema: []
1903
1923
  },
1904
- name: RULE_NAME$33,
1905
- create: create$33,
1924
+ name: RULE_NAME$36,
1925
+ create: create$36,
1906
1926
  defaultOptions: []
1907
1927
  });
1908
- function create$33(context) {
1928
+ function create$36(context) {
1909
1929
  const services = ESLintUtils.getParserServices(context, false);
1910
1930
  const checker = services.program.getTypeChecker();
1911
- return { JSXSpreadAttribute(node) {
1931
+ return defineRuleListener({ JSXSpreadAttribute(node) {
1912
1932
  for (const type of unionConstituents(getConstrainedTypeAtLocation(services, node.argument))) {
1913
1933
  const key = type.getProperty("key");
1914
1934
  if (key == null) continue;
@@ -1918,12 +1938,12 @@ function create$33(context) {
1918
1938
  node
1919
1939
  });
1920
1940
  }
1921
- } };
1941
+ } });
1922
1942
  }
1923
1943
 
1924
1944
  //#endregion
1925
1945
  //#region src/rules/no-leaked-conditional-rendering.ts
1926
- const RULE_NAME$32 = "no-leaked-conditional-rendering";
1946
+ const RULE_NAME$35 = "no-leaked-conditional-rendering";
1927
1947
  var no_leaked_conditional_rendering_default = createRule({
1928
1948
  meta: {
1929
1949
  type: "problem",
@@ -1931,11 +1951,11 @@ var no_leaked_conditional_rendering_default = createRule({
1931
1951
  messages: { default: "Potential leaked value {{value}} that might cause unintentionally rendered values or rendering crashes." },
1932
1952
  schema: []
1933
1953
  },
1934
- name: RULE_NAME$32,
1935
- create: create$32,
1954
+ name: RULE_NAME$35,
1955
+ create: create$35,
1936
1956
  defaultOptions: []
1937
1957
  });
1938
- function create$32(context) {
1958
+ function create$35(context) {
1939
1959
  if (!context.sourceCode.text.includes("&&")) return {};
1940
1960
  const { version } = getSettingsFromContext(context);
1941
1961
  const allowedVariants = [
@@ -1987,12 +2007,12 @@ function create$32(context) {
1987
2007
  return match(variableDefNode).with({ init: P.select({ type: P.not(AST_NODE_TYPES.VariableDeclaration) }) }, getReportDescriptor).otherwise(() => unit);
1988
2008
  }).otherwise(() => unit);
1989
2009
  }
1990
- return { JSXExpressionContainer: flow(getReportDescriptor, report(context)) };
2010
+ return defineRuleListener({ JSXExpressionContainer: flow(getReportDescriptor, report(context)) });
1991
2011
  }
1992
2012
 
1993
2013
  //#endregion
1994
2014
  //#region src/rules/no-missing-component-display-name.ts
1995
- const RULE_NAME$31 = "no-missing-component-display-name";
2015
+ const RULE_NAME$34 = "no-missing-component-display-name";
1996
2016
  var no_missing_component_display_name_default = createRule({
1997
2017
  meta: {
1998
2018
  type: "problem",
@@ -2000,11 +2020,11 @@ var no_missing_component_display_name_default = createRule({
2000
2020
  messages: { default: "Add missing 'displayName' for component." },
2001
2021
  schema: []
2002
2022
  },
2003
- name: RULE_NAME$31,
2004
- create: create$31,
2023
+ name: RULE_NAME$34,
2024
+ create: create$34,
2005
2025
  defaultOptions: []
2006
2026
  });
2007
- function create$31(context) {
2027
+ function create$34(context) {
2008
2028
  if (!context.sourceCode.text.includes("memo") && !context.sourceCode.text.includes("forwardRef")) return {};
2009
2029
  const { ctx, visitor } = core.useComponentCollector(context, {
2010
2030
  collectDisplayName: true,
@@ -2026,7 +2046,7 @@ function create$31(context) {
2026
2046
 
2027
2047
  //#endregion
2028
2048
  //#region src/rules/no-missing-context-display-name.ts
2029
- const RULE_NAME$30 = "no-missing-context-display-name";
2049
+ const RULE_NAME$33 = "no-missing-context-display-name";
2030
2050
  var no_missing_context_display_name_default = createRule({
2031
2051
  meta: {
2032
2052
  type: "problem",
@@ -2035,15 +2055,15 @@ var no_missing_context_display_name_default = createRule({
2035
2055
  messages: { default: "Add missing 'displayName' for context." },
2036
2056
  schema: []
2037
2057
  },
2038
- name: RULE_NAME$30,
2039
- create: create$30,
2058
+ name: RULE_NAME$33,
2059
+ create: create$33,
2040
2060
  defaultOptions: []
2041
2061
  });
2042
- function create$30(context) {
2062
+ function create$33(context) {
2043
2063
  if (!context.sourceCode.text.includes("createContext")) return {};
2044
2064
  const createCalls = [];
2045
2065
  const displayNameAssignments = [];
2046
- return {
2066
+ return defineRuleListener({
2047
2067
  [ast.SEL_DISPLAY_NAME_ASSIGNMENT_EXPRESSION](node) {
2048
2068
  displayNameAssignments.push(node);
2049
2069
  },
@@ -2086,12 +2106,12 @@ function create$30(context) {
2086
2106
  });
2087
2107
  }
2088
2108
  }
2089
- };
2109
+ });
2090
2110
  }
2091
2111
 
2092
2112
  //#endregion
2093
2113
  //#region src/rules/no-missing-key.ts
2094
- const RULE_NAME$29 = "no-missing-key";
2114
+ const RULE_NAME$32 = "no-missing-key";
2095
2115
  var no_missing_key_default = createRule({
2096
2116
  meta: {
2097
2117
  type: "problem",
@@ -2102,11 +2122,11 @@ var no_missing_key_default = createRule({
2102
2122
  },
2103
2123
  schema: []
2104
2124
  },
2105
- name: RULE_NAME$29,
2106
- create: create$29,
2125
+ name: RULE_NAME$32,
2126
+ create: create$32,
2107
2127
  defaultOptions: []
2108
2128
  });
2109
- function create$29(ctx) {
2129
+ function create$32(ctx) {
2110
2130
  let inChildrenToArray = false;
2111
2131
  function check(node) {
2112
2132
  if (node.type === AST_NODE_TYPES.JSXElement) return core.getJsxAttribute(ctx, node)("key") == null ? {
@@ -2129,9 +2149,16 @@ function create$29(ctx) {
2129
2149
  }
2130
2150
  }
2131
2151
  function checkBlock(node) {
2132
- return ast.getNestedReturnStatements(node).filter((stmt) => stmt.argument != null).map((stmt) => check(stmt.argument)).filter((d) => d != null);
2152
+ const descriptors = [];
2153
+ for (const stmt of ast.getNestedReturnStatements(node)) {
2154
+ if (stmt.argument == null) continue;
2155
+ const desc = check(stmt.argument);
2156
+ if (desc == null) continue;
2157
+ descriptors.push(desc);
2158
+ }
2159
+ return descriptors;
2133
2160
  }
2134
- return {
2161
+ return defineRuleListener({
2135
2162
  ArrayExpression(node) {
2136
2163
  if (inChildrenToArray) return;
2137
2164
  const elements = node.elements.filter(ast.is(AST_NODE_TYPES.JSXElement));
@@ -2165,12 +2192,12 @@ function create$29(ctx) {
2165
2192
  node
2166
2193
  });
2167
2194
  }
2168
- };
2195
+ });
2169
2196
  }
2170
2197
 
2171
2198
  //#endregion
2172
2199
  //#region src/rules/no-misused-capture-owner-stack.ts
2173
- const RULE_NAME$28 = "no-misused-capture-owner-stack";
2200
+ const RULE_NAME$31 = "no-misused-capture-owner-stack";
2174
2201
  var no_misused_capture_owner_stack_default = createRule({
2175
2202
  meta: {
2176
2203
  type: "problem",
@@ -2181,14 +2208,14 @@ var no_misused_capture_owner_stack_default = createRule({
2181
2208
  },
2182
2209
  schema: []
2183
2210
  },
2184
- name: RULE_NAME$28,
2185
- create: create$28,
2211
+ name: RULE_NAME$31,
2212
+ create: create$31,
2186
2213
  defaultOptions: []
2187
2214
  });
2188
- function create$28(context) {
2215
+ function create$31(context) {
2189
2216
  if (!context.sourceCode.text.includes("captureOwnerStack")) return {};
2190
2217
  const { importSource } = getSettingsFromContext(context);
2191
- return {
2218
+ return defineRuleListener({
2192
2219
  CallExpression(node) {
2193
2220
  if (!core.isCaptureOwnerStackCall(context, node)) return;
2194
2221
  if (ast.findParentNode(node, isDevelopmentOnlyCheck) == null) context.report({
@@ -2207,7 +2234,7 @@ function create$28(context) {
2207
2234
  });
2208
2235
  }
2209
2236
  }
2210
- };
2237
+ });
2211
2238
  }
2212
2239
  function isDevelopmentOnlyCheck(node) {
2213
2240
  if (node.type !== AST_NODE_TYPES.IfStatement) return false;
@@ -2216,7 +2243,7 @@ function isDevelopmentOnlyCheck(node) {
2216
2243
 
2217
2244
  //#endregion
2218
2245
  //#region src/rules/no-nested-component-definitions.ts
2219
- const RULE_NAME$27 = "no-nested-component-definitions";
2246
+ const RULE_NAME$30 = "no-nested-component-definitions";
2220
2247
  var no_nested_component_definitions_default = createRule({
2221
2248
  meta: {
2222
2249
  type: "problem",
@@ -2224,11 +2251,11 @@ var no_nested_component_definitions_default = createRule({
2224
2251
  messages: { default: "Do not nest component definitions inside other components or props. {{suggestion}}" },
2225
2252
  schema: []
2226
2253
  },
2227
- name: RULE_NAME$27,
2228
- create: create$27,
2254
+ name: RULE_NAME$30,
2255
+ create: create$30,
2229
2256
  defaultOptions: []
2230
2257
  });
2231
- function create$27(context) {
2258
+ function create$30(context) {
2232
2259
  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;
2233
2260
  const fCollector = core.useComponentCollector(context, { hint });
2234
2261
  const cCollector = core.useComponentCollectorLegacy(context);
@@ -2333,7 +2360,7 @@ function isInsideCreateElementProps(context, node) {
2333
2360
 
2334
2361
  //#endregion
2335
2362
  //#region src/rules/no-nested-lazy-component-declarations.ts
2336
- const RULE_NAME$26 = "no-nested-lazy-component-declarations";
2363
+ const RULE_NAME$29 = "no-nested-lazy-component-declarations";
2337
2364
  var no_nested_lazy_component_declarations_default = createRule({
2338
2365
  meta: {
2339
2366
  type: "problem",
@@ -2341,11 +2368,11 @@ var no_nested_lazy_component_declarations_default = createRule({
2341
2368
  messages: { default: "Do not declare lazy components inside other components. Instead, always declare them at the top level of your module." },
2342
2369
  schema: []
2343
2370
  },
2344
- name: RULE_NAME$26,
2345
- create: create$26,
2371
+ name: RULE_NAME$29,
2372
+ create: create$29,
2346
2373
  defaultOptions: []
2347
2374
  });
2348
- function create$26(context) {
2375
+ function create$29(context) {
2349
2376
  const hint = core.ComponentDetectionHint.None;
2350
2377
  const collector = core.useComponentCollector(context, { hint });
2351
2378
  const collectorLegacy = core.useComponentCollectorLegacy(context);
@@ -2374,7 +2401,7 @@ function create$26(context) {
2374
2401
 
2375
2402
  //#endregion
2376
2403
  //#region src/rules/no-redundant-should-component-update.ts
2377
- const RULE_NAME$25 = "no-redundant-should-component-update";
2404
+ const RULE_NAME$28 = "no-redundant-should-component-update";
2378
2405
  function isShouldComponentUpdate(node) {
2379
2406
  return ast.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name === "shouldComponentUpdate";
2380
2407
  }
@@ -2385,11 +2412,11 @@ var no_redundant_should_component_update_default = createRule({
2385
2412
  messages: { default: "'{{componentName}}' does not need 'shouldComponentUpdate' when extending 'React.PureComponent'." },
2386
2413
  schema: []
2387
2414
  },
2388
- name: RULE_NAME$25,
2389
- create: create$25,
2415
+ name: RULE_NAME$28,
2416
+ create: create$28,
2390
2417
  defaultOptions: []
2391
2418
  });
2392
- function create$25(context) {
2419
+ function create$28(context) {
2393
2420
  if (!context.sourceCode.text.includes("shouldComponentUpdate")) return {};
2394
2421
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
2395
2422
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -2407,7 +2434,7 @@ function create$25(context) {
2407
2434
 
2408
2435
  //#endregion
2409
2436
  //#region src/rules/no-set-state-in-component-did-mount.ts
2410
- const RULE_NAME$24 = "no-set-state-in-component-did-mount";
2437
+ const RULE_NAME$27 = "no-set-state-in-component-did-mount";
2411
2438
  var no_set_state_in_component_did_mount_default = createRule({
2412
2439
  meta: {
2413
2440
  type: "problem",
@@ -2415,13 +2442,13 @@ var no_set_state_in_component_did_mount_default = createRule({
2415
2442
  messages: { default: "Do not call `this.setState` in `componentDidMount` outside functions such as callbacks." },
2416
2443
  schema: []
2417
2444
  },
2418
- name: RULE_NAME$24,
2419
- create: create$24,
2445
+ name: RULE_NAME$27,
2446
+ create: create$27,
2420
2447
  defaultOptions: []
2421
2448
  });
2422
- function create$24(context) {
2449
+ function create$27(context) {
2423
2450
  if (!context.sourceCode.text.includes("componentDidMount")) return {};
2424
- return { CallExpression(node) {
2451
+ return defineRuleListener({ CallExpression(node) {
2425
2452
  if (!core.isThisSetState(node)) return;
2426
2453
  const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
2427
2454
  const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentDidMount(n));
@@ -2432,12 +2459,12 @@ function create$24(context) {
2432
2459
  messageId: "default",
2433
2460
  node
2434
2461
  });
2435
- } };
2462
+ } });
2436
2463
  }
2437
2464
 
2438
2465
  //#endregion
2439
2466
  //#region src/rules/no-set-state-in-component-did-update.ts
2440
- const RULE_NAME$23 = "no-set-state-in-component-did-update";
2467
+ const RULE_NAME$26 = "no-set-state-in-component-did-update";
2441
2468
  var no_set_state_in_component_did_update_default = createRule({
2442
2469
  meta: {
2443
2470
  type: "problem",
@@ -2445,13 +2472,13 @@ var no_set_state_in_component_did_update_default = createRule({
2445
2472
  messages: { default: "Do not call `this.setState` in `componentDidUpdate` outside functions such as callbacks." },
2446
2473
  schema: []
2447
2474
  },
2448
- name: RULE_NAME$23,
2449
- create: create$23,
2475
+ name: RULE_NAME$26,
2476
+ create: create$26,
2450
2477
  defaultOptions: []
2451
2478
  });
2452
- function create$23(context) {
2479
+ function create$26(context) {
2453
2480
  if (!context.sourceCode.text.includes("componentDidUpdate")) return {};
2454
- return { CallExpression(node) {
2481
+ return defineRuleListener({ CallExpression(node) {
2455
2482
  if (!core.isThisSetState(node)) return;
2456
2483
  const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
2457
2484
  const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentDidUpdate(n));
@@ -2462,12 +2489,12 @@ function create$23(context) {
2462
2489
  messageId: "default",
2463
2490
  node
2464
2491
  });
2465
- } };
2492
+ } });
2466
2493
  }
2467
2494
 
2468
2495
  //#endregion
2469
2496
  //#region src/rules/no-set-state-in-component-will-update.ts
2470
- const RULE_NAME$22 = "no-set-state-in-component-will-update";
2497
+ const RULE_NAME$25 = "no-set-state-in-component-will-update";
2471
2498
  var no_set_state_in_component_will_update_default = createRule({
2472
2499
  meta: {
2473
2500
  type: "problem",
@@ -2475,13 +2502,13 @@ var no_set_state_in_component_will_update_default = createRule({
2475
2502
  messages: { default: "Do not call `this.setState` in `componentWillUpdate` outside functions such as callbacks." },
2476
2503
  schema: []
2477
2504
  },
2478
- name: RULE_NAME$22,
2479
- create: create$22,
2505
+ name: RULE_NAME$25,
2506
+ create: create$25,
2480
2507
  defaultOptions: []
2481
2508
  });
2482
- function create$22(context) {
2509
+ function create$25(context) {
2483
2510
  if (!context.sourceCode.text.includes("componentWillUpdate")) return {};
2484
- return { CallExpression(node) {
2511
+ return defineRuleListener({ CallExpression(node) {
2485
2512
  if (!core.isThisSetState(node)) return;
2486
2513
  const enclosingClassNode = ast.findParentNode(node, core.isClassComponent);
2487
2514
  const enclosingMethodNode = ast.findParentNode(node, (n) => n === enclosingClassNode || core.isComponentWillUpdate(n));
@@ -2492,12 +2519,12 @@ function create$22(context) {
2492
2519
  messageId: "default",
2493
2520
  node
2494
2521
  });
2495
- } };
2522
+ } });
2496
2523
  }
2497
2524
 
2498
2525
  //#endregion
2499
2526
  //#region src/rules/no-unnecessary-use-callback.ts
2500
- const RULE_NAME$21 = "no-unnecessary-use-callback";
2527
+ const RULE_NAME$24 = "no-unnecessary-use-callback";
2501
2528
  var no_unnecessary_use_callback_default = createRule({
2502
2529
  meta: {
2503
2530
  type: "problem",
@@ -2508,13 +2535,13 @@ var no_unnecessary_use_callback_default = createRule({
2508
2535
  },
2509
2536
  schema: []
2510
2537
  },
2511
- name: RULE_NAME$21,
2512
- create: create$21,
2538
+ name: RULE_NAME$24,
2539
+ create: create$24,
2513
2540
  defaultOptions: []
2514
2541
  });
2515
- function create$21(context) {
2542
+ function create$24(context) {
2516
2543
  if (!context.sourceCode.text.includes("useCallback")) return {};
2517
- return { VariableDeclarator(node) {
2544
+ return defineRuleListener({ VariableDeclarator(node) {
2518
2545
  const { id, init } = node;
2519
2546
  if (id.type !== AST_NODE_TYPES.Identifier || init?.type !== AST_NODE_TYPES.CallExpression || !core.isUseCallbackCall(init)) return;
2520
2547
  const [cbk, ...rest] = context.sourceCode.getDeclaredVariables(node);
@@ -2526,7 +2553,7 @@ function create$21(context) {
2526
2553
  const [arg0, arg1] = init.arguments;
2527
2554
  if (arg0 == null || arg1 == null) return;
2528
2555
  if (!match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
2529
- const variableNode = getVariableDefinitionNode(findVariable(n.name, scope), 0);
2556
+ const variableNode = getVariableInitializer(findVariable(n.name, scope), 0);
2530
2557
  if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) return false;
2531
2558
  return variableNode.elements.length === 0;
2532
2559
  }).otherwise(() => false)) {
@@ -2537,7 +2564,7 @@ function create$21(context) {
2537
2564
  if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) return n.body;
2538
2565
  return n;
2539
2566
  }).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
2540
- const variableNode = getVariableDefinitionNode(findVariable(n.name, scope), 0);
2567
+ const variableNode = getVariableInitializer(findVariable(n.name, scope), 0);
2541
2568
  if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) return null;
2542
2569
  return variableNode;
2543
2570
  }).otherwise(() => null);
@@ -2550,7 +2577,7 @@ function create$21(context) {
2550
2577
  return;
2551
2578
  }
2552
2579
  report(context)(checkForUsageInsideUseEffectReport);
2553
- } };
2580
+ } });
2554
2581
  }
2555
2582
  function checkForUsageInsideUseEffect$1(sourceCode, node) {
2556
2583
  if (!/use\w*Effect/u.test(sourceCode.text)) return;
@@ -2574,7 +2601,7 @@ function checkForUsageInsideUseEffect$1(sourceCode, node) {
2574
2601
 
2575
2602
  //#endregion
2576
2603
  //#region src/rules/no-unnecessary-use-memo.ts
2577
- const RULE_NAME$20 = "no-unnecessary-use-memo";
2604
+ const RULE_NAME$23 = "no-unnecessary-use-memo";
2578
2605
  var no_unnecessary_use_memo_default = createRule({
2579
2606
  meta: {
2580
2607
  type: "problem",
@@ -2585,13 +2612,13 @@ var no_unnecessary_use_memo_default = createRule({
2585
2612
  },
2586
2613
  schema: []
2587
2614
  },
2588
- name: RULE_NAME$20,
2589
- create: create$20,
2615
+ name: RULE_NAME$23,
2616
+ create: create$23,
2590
2617
  defaultOptions: []
2591
2618
  });
2592
- function create$20(context) {
2619
+ function create$23(context) {
2593
2620
  if (!context.sourceCode.text.includes("useMemo")) return {};
2594
- return { VariableDeclarator(node) {
2621
+ return defineRuleListener({ VariableDeclarator(node) {
2595
2622
  const { id, init } = node;
2596
2623
  if (id.type !== AST_NODE_TYPES.Identifier || init?.type !== AST_NODE_TYPES.CallExpression || !core.isUseMemoCall(init)) return;
2597
2624
  const [mem, ...rest] = context.sourceCode.getDeclaredVariables(node);
@@ -2607,7 +2634,7 @@ function create$20(context) {
2607
2634
  return;
2608
2635
  }
2609
2636
  if (!match(arg1).with({ type: AST_NODE_TYPES.ArrayExpression }, (n) => n.elements.length === 0).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
2610
- const variableNode = getVariableDefinitionNode(findVariable(n.name, scope), 0);
2637
+ const variableNode = getVariableInitializer(findVariable(n.name, scope), 0);
2611
2638
  if (variableNode?.type !== AST_NODE_TYPES.ArrayExpression) return false;
2612
2639
  return variableNode.elements.length === 0;
2613
2640
  }).otherwise(() => false)) {
@@ -2618,7 +2645,7 @@ function create$20(context) {
2618
2645
  if (n.body.type === AST_NODE_TYPES.ArrowFunctionExpression) return n.body;
2619
2646
  return n;
2620
2647
  }).with({ type: AST_NODE_TYPES.FunctionExpression }, identity).with({ type: AST_NODE_TYPES.Identifier }, (n) => {
2621
- const variableNode = getVariableDefinitionNode(findVariable(n.name, scope), 0);
2648
+ const variableNode = getVariableInitializer(findVariable(n.name, scope), 0);
2622
2649
  if (variableNode?.type !== AST_NODE_TYPES.ArrowFunctionExpression && variableNode?.type !== AST_NODE_TYPES.FunctionExpression) return null;
2623
2650
  return variableNode;
2624
2651
  }).otherwise(() => null);
@@ -2631,7 +2658,7 @@ function create$20(context) {
2631
2658
  return;
2632
2659
  }
2633
2660
  report(context)(checkForUsageInsideUseEffectReport);
2634
- } };
2661
+ } });
2635
2662
  }
2636
2663
  function checkForUsageInsideUseEffect(sourceCode, node) {
2637
2664
  if (!/use\w*Effect/u.test(sourceCode.text)) return;
@@ -2655,7 +2682,7 @@ function checkForUsageInsideUseEffect(sourceCode, node) {
2655
2682
 
2656
2683
  //#endregion
2657
2684
  //#region src/rules/no-unnecessary-use-prefix.ts
2658
- const RULE_NAME$19 = "no-unnecessary-use-prefix";
2685
+ const RULE_NAME$22 = "no-unnecessary-use-prefix";
2659
2686
  const WELL_KNOWN_HOOKS = ["useMDXComponents"];
2660
2687
  function containsUseComments(context, node) {
2661
2688
  return context.sourceCode.getCommentsInside(node).some(({ value }) => /use\([\s\S]*?\)/u.test(value) || /use[A-Z0-9]\w*\([\s\S]*?\)/u.test(value));
@@ -2667,11 +2694,11 @@ var no_unnecessary_use_prefix_default = createRule({
2667
2694
  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." },
2668
2695
  schema: []
2669
2696
  },
2670
- name: RULE_NAME$19,
2671
- create: create$19,
2697
+ name: RULE_NAME$22,
2698
+ create: create$22,
2672
2699
  defaultOptions: []
2673
2700
  });
2674
- function create$19(context) {
2701
+ function create$22(context) {
2675
2702
  const { ctx, visitor } = core.useHookCollector(context);
2676
2703
  return defineRuleListener(visitor, { "Program:exit"(program) {
2677
2704
  for (const { id, name, node, hookCalls } of ctx.getAllHooks(program)) {
@@ -2691,7 +2718,7 @@ function create$19(context) {
2691
2718
 
2692
2719
  //#endregion
2693
2720
  //#region src/rules/no-unsafe-component-will-mount.ts
2694
- const RULE_NAME$18 = "no-unsafe-component-will-mount";
2721
+ const RULE_NAME$21 = "no-unsafe-component-will-mount";
2695
2722
  var no_unsafe_component_will_mount_default = createRule({
2696
2723
  meta: {
2697
2724
  type: "problem",
@@ -2699,11 +2726,11 @@ var no_unsafe_component_will_mount_default = createRule({
2699
2726
  messages: { default: "Do not use 'UNSAFE_componentWillMount'." },
2700
2727
  schema: []
2701
2728
  },
2702
- name: RULE_NAME$18,
2703
- create: create$18,
2729
+ name: RULE_NAME$21,
2730
+ create: create$21,
2704
2731
  defaultOptions: []
2705
2732
  });
2706
- function create$18(context) {
2733
+ function create$21(context) {
2707
2734
  if (!context.sourceCode.text.includes("UNSAFE_componentWillMount")) return {};
2708
2735
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
2709
2736
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -2719,7 +2746,7 @@ function create$18(context) {
2719
2746
 
2720
2747
  //#endregion
2721
2748
  //#region src/rules/no-unsafe-component-will-receive-props.ts
2722
- const RULE_NAME$17 = "no-unsafe-component-will-receive-props";
2749
+ const RULE_NAME$20 = "no-unsafe-component-will-receive-props";
2723
2750
  var no_unsafe_component_will_receive_props_default = createRule({
2724
2751
  meta: {
2725
2752
  type: "problem",
@@ -2727,11 +2754,11 @@ var no_unsafe_component_will_receive_props_default = createRule({
2727
2754
  messages: { default: "Do not use 'UNSAFE_componentWillReceiveProps'." },
2728
2755
  schema: []
2729
2756
  },
2730
- name: RULE_NAME$17,
2731
- create: create$17,
2757
+ name: RULE_NAME$20,
2758
+ create: create$20,
2732
2759
  defaultOptions: []
2733
2760
  });
2734
- function create$17(context) {
2761
+ function create$20(context) {
2735
2762
  if (!context.sourceCode.text.includes("UNSAFE_componentWillReceiveProps")) return {};
2736
2763
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
2737
2764
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -2747,7 +2774,7 @@ function create$17(context) {
2747
2774
 
2748
2775
  //#endregion
2749
2776
  //#region src/rules/no-unsafe-component-will-update.ts
2750
- const RULE_NAME$16 = "no-unsafe-component-will-update";
2777
+ const RULE_NAME$19 = "no-unsafe-component-will-update";
2751
2778
  var no_unsafe_component_will_update_default = createRule({
2752
2779
  meta: {
2753
2780
  type: "problem",
@@ -2755,11 +2782,11 @@ var no_unsafe_component_will_update_default = createRule({
2755
2782
  messages: { default: "Do not use 'UNSAFE_componentWillUpdate'." },
2756
2783
  schema: []
2757
2784
  },
2758
- name: RULE_NAME$16,
2759
- create: create$16,
2785
+ name: RULE_NAME$19,
2786
+ create: create$19,
2760
2787
  defaultOptions: []
2761
2788
  });
2762
- function create$16(context) {
2789
+ function create$19(context) {
2763
2790
  if (!context.sourceCode.text.includes("UNSAFE_componentWillUpdate")) return {};
2764
2791
  const { ctx, visitor } = core.useComponentCollectorLegacy(context);
2765
2792
  return defineRuleListener(visitor, { "Program:exit"(program) {
@@ -2775,7 +2802,7 @@ function create$16(context) {
2775
2802
 
2776
2803
  //#endregion
2777
2804
  //#region src/rules/no-unstable-context-value.ts
2778
- const RULE_NAME$15 = "no-unstable-context-value";
2805
+ const RULE_NAME$18 = "no-unstable-context-value";
2779
2806
  var no_unstable_context_value_default = createRule({
2780
2807
  meta: {
2781
2808
  type: "problem",
@@ -2783,13 +2810,14 @@ var no_unstable_context_value_default = createRule({
2783
2810
  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}}" },
2784
2811
  schema: []
2785
2812
  },
2786
- name: RULE_NAME$15,
2787
- create: create$15,
2813
+ name: RULE_NAME$18,
2814
+ create: create$18,
2788
2815
  defaultOptions: []
2789
2816
  });
2790
- function create$15(context) {
2791
- const { isCompilerEnabled, version } = getSettingsFromContext(context);
2792
- if (isCompilerEnabled && ast.isDirectiveInFile(context.sourceCode.ast, "use memo")) return {};
2817
+ function create$18(context) {
2818
+ const { compilationMode, version } = getSettingsFromContext(context);
2819
+ if (compilationMode === "infer" || compilationMode === "all") return {};
2820
+ if (compilationMode === "annotation" && ast.isDirectiveInFile(context.sourceCode.ast, "use memo")) return {};
2793
2821
  const isReact18OrBelow = compare(version, "19.0.0", "<");
2794
2822
  const { ctx, visitor } = core.useComponentCollector(context);
2795
2823
  const constructions = /* @__PURE__ */ new WeakMap();
@@ -2800,7 +2828,7 @@ function create$15(context) {
2800
2828
  if (!isContextName(selfName, isReact18OrBelow)) return;
2801
2829
  const functionEntry = ctx.getCurrentEntry();
2802
2830
  if (functionEntry == null) return;
2803
- if (isCompilerEnabled && ast.isDirectiveInFunction(functionEntry.node, "use memo")) return;
2831
+ if (compilationMode === "annotation" && ast.isDirectiveInFunction(functionEntry.node, "use memo")) return;
2804
2832
  const attribute = node.attributes.find((attribute) => attribute.type === AST_NODE_TYPES.JSXAttribute && attribute.name.name === "value");
2805
2833
  if (attribute == null || !("value" in attribute)) return;
2806
2834
  const value = attribute.value;
@@ -2812,18 +2840,20 @@ function create$15(context) {
2812
2840
  getOrElseUpdate(constructions, functionEntry.node, () => []).push(construction);
2813
2841
  },
2814
2842
  "Program:exit"(program) {
2815
- for (const { node: component, directives } of ctx.getAllComponents(program)) for (const construction of constructions.get(component) ?? []) {
2816
- if (directives.some((d) => d.directive === "use memo")) return;
2817
- const { kind, node: constructionNode } = construction;
2818
- const suggestion = kind === "function" ? "Consider wrapping it in a useCallback hook." : "Consider wrapping it in a useMemo hook.";
2819
- context.report({
2820
- messageId: "unstableContextValue",
2821
- node: constructionNode,
2822
- data: {
2823
- kind: ast.getHumanReadableKind(constructionNode),
2824
- suggestion
2825
- }
2826
- });
2843
+ for (const { node: component, directives } of ctx.getAllComponents(program)) {
2844
+ if (compilationMode === "annotation" && directives.some((d) => d.directive === "use memo")) continue;
2845
+ for (const construction of constructions.get(component) ?? []) {
2846
+ const { kind, node: constructionNode } = construction;
2847
+ const suggestion = kind === "function" ? "Consider wrapping it in a useCallback hook." : "Consider wrapping it in a useMemo hook.";
2848
+ context.report({
2849
+ messageId: "unstableContextValue",
2850
+ node: constructionNode,
2851
+ data: {
2852
+ kind: ast.getHumanReadableKind(constructionNode),
2853
+ suggestion
2854
+ }
2855
+ });
2856
+ }
2827
2857
  }
2828
2858
  }
2829
2859
  });
@@ -2836,9 +2866,9 @@ function isContextName(name, isReact18OrBelow) {
2836
2866
 
2837
2867
  //#endregion
2838
2868
  //#region src/rules/no-unstable-default-props.ts
2839
- const RULE_NAME$14 = "no-unstable-default-props";
2840
- const defaultOptions$1 = [{ safeDefaultProps: [] }];
2841
- const schema$1 = [{
2869
+ const RULE_NAME$17 = "no-unstable-default-props";
2870
+ const defaultOptions$2 = [{ safeDefaultProps: [] }];
2871
+ const schema$2 = [{
2842
2872
  type: "object",
2843
2873
  additionalProperties: false,
2844
2874
  properties: { safeDefaultProps: {
@@ -2851,11 +2881,11 @@ var no_unstable_default_props_default = createRule({
2851
2881
  type: "problem",
2852
2882
  docs: { description: "Prevents using referential-type values as default props in object destructuring." },
2853
2883
  messages: { default: "A/an '{{kind}}' as default prop. This could lead to potential infinite render loop in React. Use a variable instead of '{{kind}}'." },
2854
- schema: schema$1
2884
+ schema: schema$2
2855
2885
  },
2856
- name: RULE_NAME$14,
2857
- create: create$14,
2858
- defaultOptions: defaultOptions$1
2886
+ name: RULE_NAME$17,
2887
+ create: create$17,
2888
+ defaultOptions: defaultOptions$2
2859
2889
  });
2860
2890
  function extractIdentifier(node) {
2861
2891
  if (node.type === AST_NODE_TYPES.NewExpression && node.callee.type === AST_NODE_TYPES.Identifier) return node.callee.name;
@@ -2865,9 +2895,10 @@ function extractIdentifier(node) {
2865
2895
  }
2866
2896
  return null;
2867
2897
  }
2868
- function create$14(context, [options]) {
2869
- const { isCompilerEnabled } = getSettingsFromContext(context);
2870
- if (isCompilerEnabled && ast.isDirectiveInFile(context.sourceCode.ast, "use memo")) return {};
2898
+ function create$17(context, [options]) {
2899
+ const { compilationMode } = getSettingsFromContext(context);
2900
+ if (compilationMode === "infer" || compilationMode === "all") return {};
2901
+ if (compilationMode === "annotation" && ast.isDirectiveInFile(context.sourceCode.ast, "use memo")) return {};
2871
2902
  const { ctx, visitor } = core.useComponentCollector(context);
2872
2903
  const declarators = /* @__PURE__ */ new WeakMap();
2873
2904
  const { safeDefaultProps = [] } = options;
@@ -2910,7 +2941,7 @@ function create$14(context, [options]) {
2910
2941
 
2911
2942
  //#endregion
2912
2943
  //#region src/rules/no-unused-class-component-members.ts
2913
- const RULE_NAME$13 = "no-unused-class-component-members";
2944
+ const RULE_NAME$16 = "no-unused-class-component-members";
2914
2945
  const LIFECYCLE_METHODS = new Set([
2915
2946
  "componentDidCatch",
2916
2947
  "componentDidMount",
@@ -2941,11 +2972,11 @@ var no_unused_class_component_members_default = createRule({
2941
2972
  messages: { default: "Unused method or property '{{methodName}}'' of class '{{className}}'." },
2942
2973
  schema: []
2943
2974
  },
2944
- name: RULE_NAME$13,
2945
- create: create$13,
2975
+ name: RULE_NAME$16,
2976
+ create: create$16,
2946
2977
  defaultOptions: []
2947
2978
  });
2948
- function create$13(context) {
2979
+ function create$16(context) {
2949
2980
  const classStack = [];
2950
2981
  const methodStack = [];
2951
2982
  const propertyDefs = /* @__PURE__ */ new WeakMap();
@@ -2987,7 +3018,7 @@ function create$13(context) {
2987
3018
  function methodExit() {
2988
3019
  methodStack.pop();
2989
3020
  }
2990
- return {
3021
+ return defineRuleListener({
2991
3022
  ClassDeclaration: classEnter,
2992
3023
  "ClassDeclaration:exit": classExit,
2993
3024
  ClassExpression: classEnter,
@@ -3021,12 +3052,12 @@ function create$13(context) {
3021
3052
  }
3022
3053
  }
3023
3054
  }
3024
- };
3055
+ });
3025
3056
  }
3026
3057
 
3027
3058
  //#endregion
3028
3059
  //#region src/rules/no-unused-props.ts
3029
- const RULE_NAME$12 = "no-unused-props";
3060
+ const RULE_NAME$15 = "no-unused-props";
3030
3061
  var no_unused_props_default = createRule({
3031
3062
  meta: {
3032
3063
  type: "problem",
@@ -3034,15 +3065,15 @@ var no_unused_props_default = createRule({
3034
3065
  messages: { default: "Prop `{{name}}` is declared but never used" },
3035
3066
  schema: []
3036
3067
  },
3037
- name: RULE_NAME$12,
3038
- create: create$12,
3068
+ name: RULE_NAME$15,
3069
+ create: create$15,
3039
3070
  defaultOptions: []
3040
3071
  });
3041
- function create$12(context) {
3072
+ function create$15(context) {
3042
3073
  const services = ESLintUtils.getParserServices(context, false);
3074
+ const checker = services.program.getTypeChecker();
3043
3075
  const { ctx, visitor } = core.useComponentCollector(context);
3044
3076
  return defineRuleListener(visitor, { "Program:exit"(program) {
3045
- const checker = services.program.getTypeChecker();
3046
3077
  const totalDeclaredProps = /* @__PURE__ */ new Set();
3047
3078
  const totalUsedProps = /* @__PURE__ */ new Set();
3048
3079
  for (const component of ctx.getAllComponents(program)) {
@@ -3117,7 +3148,9 @@ function collectUsedPropKeysOfReference(context, usedPropKeys, identifier, ref)
3117
3148
  function getKeyOfExpression(expr) {
3118
3149
  switch (expr.type) {
3119
3150
  case AST_NODE_TYPES.Identifier: return expr.name;
3120
- case AST_NODE_TYPES.Literal: if (typeof expr.value === "string") return expr.value;
3151
+ case AST_NODE_TYPES.Literal:
3152
+ if (typeof expr.value === "string") return expr.value;
3153
+ break;
3121
3154
  }
3122
3155
  return null;
3123
3156
  }
@@ -3136,7 +3169,7 @@ function reportUnusedProp(context, services, prop) {
3136
3169
 
3137
3170
  //#endregion
3138
3171
  //#region src/rules/no-unused-state.ts
3139
- const RULE_NAME$11 = "no-unused-state";
3172
+ const RULE_NAME$14 = "no-unused-state";
3140
3173
  function isKeyLiteral(node, key) {
3141
3174
  return match(key).with({ type: AST_NODE_TYPES.Literal }, constTrue).with({
3142
3175
  type: AST_NODE_TYPES.TemplateLiteral,
@@ -3150,11 +3183,11 @@ var no_unused_state_default = createRule({
3150
3183
  messages: { default: "Unused class component state in '{{className}}'" },
3151
3184
  schema: []
3152
3185
  },
3153
- name: RULE_NAME$11,
3154
- create: create$11,
3186
+ name: RULE_NAME$14,
3187
+ create: create$14,
3155
3188
  defaultOptions: []
3156
3189
  });
3157
- function create$11(context) {
3190
+ function create$14(context) {
3158
3191
  const classStack = [];
3159
3192
  const methodStack = [];
3160
3193
  const constructorStack = [];
@@ -3202,7 +3235,7 @@ function create$11(context) {
3202
3235
  function constructorExit() {
3203
3236
  constructorStack.pop();
3204
3237
  }
3205
- return {
3238
+ return defineRuleListener({
3206
3239
  AssignmentExpression(node) {
3207
3240
  if (!core.isAssignmentToThisState(node)) return;
3208
3241
  const currentClass = classStack.at(-1);
@@ -3258,12 +3291,12 @@ function create$11(context) {
3258
3291
  isUsed: true
3259
3292
  });
3260
3293
  }
3261
- };
3294
+ });
3262
3295
  }
3263
3296
 
3264
3297
  //#endregion
3265
3298
  //#region src/rules/no-use-context.ts
3266
- const RULE_NAME$10 = "no-use-context";
3299
+ const RULE_NAME$13 = "no-use-context";
3267
3300
  var no_use_context_default = createRule({
3268
3301
  meta: {
3269
3302
  type: "problem",
@@ -3272,16 +3305,16 @@ var no_use_context_default = createRule({
3272
3305
  messages: { default: "In React 19, 'use' is preferred over 'useContext' because it is more flexible." },
3273
3306
  schema: []
3274
3307
  },
3275
- name: RULE_NAME$10,
3276
- create: create$10,
3308
+ name: RULE_NAME$13,
3309
+ create: create$13,
3277
3310
  defaultOptions: []
3278
3311
  });
3279
- function create$10(context) {
3312
+ function create$13(context) {
3280
3313
  if (!context.sourceCode.text.includes("useContext")) return {};
3281
3314
  const settings = getSettingsFromContext(context);
3282
3315
  if (compare(settings.version, "19.0.0", "<")) return {};
3283
3316
  const hookCalls = /* @__PURE__ */ new Set();
3284
- return {
3317
+ return defineRuleListener({
3285
3318
  CallExpression(node) {
3286
3319
  if (!core.isHookCall(node)) return;
3287
3320
  hookCalls.add(node);
@@ -3328,7 +3361,7 @@ function create$10(context) {
3328
3361
  });
3329
3362
  }
3330
3363
  }
3331
- };
3364
+ });
3332
3365
  }
3333
3366
  function getCorrelativeTokens(context, node) {
3334
3367
  const tokenBefore = context.sourceCode.getTokenBefore(node);
@@ -3341,7 +3374,7 @@ function getCorrelativeTokens(context, node) {
3341
3374
 
3342
3375
  //#endregion
3343
3376
  //#region src/rules/no-useless-forward-ref.ts
3344
- const RULE_NAME$9 = "no-useless-forward-ref";
3377
+ const RULE_NAME$12 = "no-useless-forward-ref";
3345
3378
  var no_useless_forward_ref_default = createRule({
3346
3379
  meta: {
3347
3380
  type: "problem",
@@ -3349,12 +3382,12 @@ var no_useless_forward_ref_default = createRule({
3349
3382
  messages: { default: "A 'forwardRef' is used with this component but no 'ref' parameter is set." },
3350
3383
  schema: []
3351
3384
  },
3352
- name: RULE_NAME$9,
3353
- create: create$9,
3385
+ name: RULE_NAME$12,
3386
+ create: create$12,
3354
3387
  defaultOptions: []
3355
3388
  });
3356
- function create$9(context) {
3357
- return { CallExpression(node) {
3389
+ function create$12(context) {
3390
+ return defineRuleListener({ CallExpression(node) {
3358
3391
  if (!core.isForwardRefCall(context, node)) return;
3359
3392
  const [component] = node.arguments;
3360
3393
  if (component == null || !ast.isFunction(component)) return;
@@ -3363,17 +3396,17 @@ function create$9(context) {
3363
3396
  messageId: "default",
3364
3397
  node: node.callee
3365
3398
  });
3366
- } };
3399
+ } });
3367
3400
  }
3368
3401
 
3369
3402
  //#endregion
3370
3403
  //#region src/rules/no-useless-fragment.ts
3371
- const RULE_NAME$8 = "no-useless-fragment";
3372
- const defaultOptions = [{
3404
+ const RULE_NAME$11 = "no-useless-fragment";
3405
+ const defaultOptions$1 = [{
3373
3406
  allowEmptyFragment: false,
3374
3407
  allowExpressions: true
3375
3408
  }];
3376
- const schema = [{
3409
+ const schema$1 = [{
3377
3410
  type: "object",
3378
3411
  additionalProperties: false,
3379
3412
  properties: {
@@ -3390,17 +3423,17 @@ const schema = [{
3390
3423
  var no_useless_fragment_default = createRule({
3391
3424
  meta: {
3392
3425
  type: "problem",
3393
- defaultOptions: [...defaultOptions],
3426
+ defaultOptions: [...defaultOptions$1],
3394
3427
  docs: { description: "Disallows useless fragment elements." },
3395
3428
  fixable: "code",
3396
3429
  messages: { default: "A fragment {{reason}} is useless." },
3397
- schema
3430
+ schema: schema$1
3398
3431
  },
3399
- name: RULE_NAME$8,
3400
- create: create$8,
3401
- defaultOptions
3432
+ name: RULE_NAME$11,
3433
+ create: create$11,
3434
+ defaultOptions: defaultOptions$1
3402
3435
  });
3403
- function create$8(context, [option]) {
3436
+ function create$11(context, [option]) {
3404
3437
  const { allowEmptyFragment = false, allowExpressions = true } = option;
3405
3438
  const jsxConfig = {
3406
3439
  ...core.getJsxConfigFromContext(context),
@@ -3473,7 +3506,7 @@ function create$8(context, [option]) {
3473
3506
  if (node.children.length === 0) return false;
3474
3507
  return !node.children.some((child) => core.isJsxText(child) && !isWhiteSpace(child) || ast.is(AST_NODE_TYPES.JSXExpressionContainer)(child));
3475
3508
  }
3476
- return {
3509
+ return defineRuleListener({
3477
3510
  JSXElement(node) {
3478
3511
  if (!core.isJsxFragmentElement(context, node, jsxConfig)) return;
3479
3512
  checkNode(context, node);
@@ -3481,7 +3514,7 @@ function create$8(context, [option]) {
3481
3514
  JSXFragment(node) {
3482
3515
  checkNode(context, node);
3483
3516
  }
3484
- };
3517
+ });
3485
3518
  }
3486
3519
  /**
3487
3520
  * Check if a Literal or JSXText node is whitespace
@@ -3508,7 +3541,7 @@ function trimLikeReact(text) {
3508
3541
 
3509
3542
  //#endregion
3510
3543
  //#region src/rules/prefer-destructuring-assignment.ts
3511
- const RULE_NAME$7 = "prefer-destructuring-assignment";
3544
+ const RULE_NAME$10 = "prefer-destructuring-assignment";
3512
3545
  var prefer_destructuring_assignment_default = createRule({
3513
3546
  meta: {
3514
3547
  type: "problem",
@@ -3516,11 +3549,11 @@ var prefer_destructuring_assignment_default = createRule({
3516
3549
  messages: { default: "Use destructuring assignment for component props." },
3517
3550
  schema: []
3518
3551
  },
3519
- name: RULE_NAME$7,
3520
- create: create$7,
3552
+ name: RULE_NAME$10,
3553
+ create: create$10,
3521
3554
  defaultOptions: []
3522
3555
  });
3523
- function create$7(context) {
3556
+ function create$10(context) {
3524
3557
  const { ctx, visitor } = core.useComponentCollector(context);
3525
3558
  return defineRuleListener(visitor, { "Program:exit"(program) {
3526
3559
  for (const component of ctx.getAllComponents(program)) {
@@ -3544,7 +3577,7 @@ function create$7(context) {
3544
3577
 
3545
3578
  //#endregion
3546
3579
  //#region src/rules/prefer-namespace-import.ts
3547
- const RULE_NAME$6 = "prefer-namespace-import";
3580
+ const RULE_NAME$9 = "prefer-namespace-import";
3548
3581
  var prefer_namespace_import_default = createRule({
3549
3582
  meta: {
3550
3583
  type: "problem",
@@ -3553,13 +3586,13 @@ var prefer_namespace_import_default = createRule({
3553
3586
  messages: { default: "Prefer importing React as 'import * as React from \"{{importSource}}\"';" },
3554
3587
  schema: []
3555
3588
  },
3556
- name: RULE_NAME$6,
3557
- create: create$6,
3589
+ name: RULE_NAME$9,
3590
+ create: create$9,
3558
3591
  defaultOptions: []
3559
3592
  });
3560
- function create$6(context) {
3593
+ function create$9(context) {
3561
3594
  const { importSource } = getSettingsFromContext(context);
3562
- return { [`ImportDeclaration[source.value="${importSource}"] ImportDefaultSpecifier`](node) {
3595
+ return defineRuleListener({ [`ImportDeclaration[source.value="${importSource}"] ImportDefaultSpecifier`](node) {
3563
3596
  const hasOtherSpecifiers = node.parent.specifiers.length > 1;
3564
3597
  context.report({
3565
3598
  messageId: "default",
@@ -3576,12 +3609,12 @@ function create$6(context) {
3576
3609
  return fixer.replaceText(node.parent, [`${importStringPrefix} * as ${node.local.name} from ${importSourceQuoted}${semi}`, `${importStringPrefix} ${specifiers} from ${importSourceQuoted}${semi}`].join("\n"));
3577
3610
  }
3578
3611
  });
3579
- } };
3612
+ } });
3580
3613
  }
3581
3614
 
3582
3615
  //#endregion
3583
3616
  //#region src/rules/prefer-read-only-props.ts
3584
- const RULE_NAME$5 = "prefer-read-only-props";
3617
+ const RULE_NAME$8 = "prefer-read-only-props";
3585
3618
  var prefer_read_only_props_default = createRule({
3586
3619
  meta: {
3587
3620
  type: "problem",
@@ -3589,11 +3622,11 @@ var prefer_read_only_props_default = createRule({
3589
3622
  messages: { default: "A function component's props should be read-only." },
3590
3623
  schema: []
3591
3624
  },
3592
- name: RULE_NAME$5,
3593
- create: create$5,
3625
+ name: RULE_NAME$8,
3626
+ create: create$8,
3594
3627
  defaultOptions: []
3595
3628
  });
3596
- function create$5(context) {
3629
+ function create$8(context) {
3597
3630
  const services = ESLintUtils.getParserServices(context, false);
3598
3631
  const checker = services.program.getTypeChecker();
3599
3632
  const { ctx, visitor } = core.useComponentCollector(context);
@@ -3632,55 +3665,9 @@ function isClassOrInterfaceReadonlyLoose(checker, type) {
3632
3665
  });
3633
3666
  }
3634
3667
 
3635
- //#endregion
3636
- //#region src/rules/prefer-use-state-lazy-initialization.ts
3637
- const RULE_NAME$4 = "prefer-use-state-lazy-initialization";
3638
- const ALLOW_LIST = [
3639
- "Boolean",
3640
- "String",
3641
- "Number"
3642
- ];
3643
- var prefer_use_state_lazy_initialization_default = createRule({
3644
- meta: {
3645
- type: "problem",
3646
- docs: { description: "Enforces wrapping function calls made inside 'useState' in an 'initializer function'." },
3647
- messages: { default: "To prevent re-computation, consider using lazy initial state for useState calls that involve function calls. Ex: 'useState(() => getValue())'." },
3648
- schema: []
3649
- },
3650
- name: RULE_NAME$4,
3651
- create: create$4,
3652
- defaultOptions: []
3653
- });
3654
- function create$4(context) {
3655
- return { CallExpression(node) {
3656
- if (!core.isUseStateCall(node)) return;
3657
- const [useStateInput] = node.arguments;
3658
- if (useStateInput == null) return;
3659
- for (const expr of ast.getNestedNewExpressions(useStateInput)) {
3660
- if (!("name" in expr.callee)) continue;
3661
- if (ALLOW_LIST.includes(expr.callee.name)) continue;
3662
- if (ast.findParentNode(expr, core.isUseCall) != null) continue;
3663
- context.report({
3664
- messageId: "default",
3665
- node: expr
3666
- });
3667
- }
3668
- for (const expr of ast.getNestedCallExpressions(useStateInput)) {
3669
- if (!("name" in expr.callee)) continue;
3670
- if (core.isHookName(expr.callee.name)) continue;
3671
- if (ALLOW_LIST.includes(expr.callee.name)) continue;
3672
- if (ast.findParentNode(expr, core.isUseCall) != null) continue;
3673
- context.report({
3674
- messageId: "default",
3675
- node: expr
3676
- });
3677
- }
3678
- } };
3679
- }
3680
-
3681
3668
  //#endregion
3682
3669
  //#region src/rules/purity.ts
3683
- const RULE_NAME$3 = "purity";
3670
+ const RULE_NAME$7 = "purity";
3684
3671
  function isImpureMemberCall(node) {
3685
3672
  if (node.callee.type !== AST_NODE_TYPES.MemberExpression) return false;
3686
3673
  const { object, property } = node.callee;
@@ -3712,11 +3699,11 @@ var purity_default = createRule({
3712
3699
  messages: { default: "Do not call '{{name}}' during render. Components and hooks must be pure. Move this call into an event handler, effect, or state initializer." },
3713
3700
  schema: []
3714
3701
  },
3715
- name: RULE_NAME$3,
3716
- create: create$3,
3702
+ name: RULE_NAME$7,
3703
+ create: create$7,
3717
3704
  defaultOptions: []
3718
3705
  });
3719
- function create$3(context) {
3706
+ function create$7(context) {
3720
3707
  const hCollector = core.useHookCollector(context);
3721
3708
  const cCollector = core.useComponentCollector(context);
3722
3709
  const cExprs = [];
@@ -3762,9 +3749,188 @@ function create$3(context) {
3762
3749
  });
3763
3750
  }
3764
3751
 
3752
+ //#endregion
3753
+ //#region src/rules/refs.ts
3754
+ const RULE_NAME$6 = "refs";
3755
+ function isWriteAccess(node) {
3756
+ const { parent } = node;
3757
+ if (parent.type === AST_NODE_TYPES.AssignmentExpression && parent.left === node) return true;
3758
+ if (parent.type === AST_NODE_TYPES.UpdateExpression && parent.argument === node) return true;
3759
+ return false;
3760
+ }
3761
+ function isInsideNestedFunction(node, boundary) {
3762
+ let current = node.parent;
3763
+ while (current != null && current !== boundary) {
3764
+ if (ast.isFunction(current)) return true;
3765
+ current = current.parent;
3766
+ }
3767
+ return false;
3768
+ }
3769
+ /**
3770
+ * Check if a ref.current access is part of a lazy initialization pattern.
3771
+ *
3772
+ * Standard:
3773
+ * if (ref.current === null) { ref.current = value; }
3774
+ *
3775
+ * Inverted (with early return):
3776
+ * if (ref.current !== null) { return ...; }
3777
+ * ref.current = computeValue();
3778
+ * @param node The MemberExpression node for ref.current
3779
+ * @param isWrite Whether this access is a write (assignment/update) or a read
3780
+ * @returns true if this access is part of a lazy initialization pattern and should be allowed during render
3781
+ */
3782
+ function isPartOfLazyInitialization(node, isWrite) {
3783
+ if (node.object.type !== AST_NODE_TYPES.Identifier) return false;
3784
+ const refName = node.object.name;
3785
+ if (isInNullCheckTest(node)) return true;
3786
+ if (findEnclosingRefNullCheckIf(node, refName) != null) return true;
3787
+ if (isWrite && isWriteAfterNullCheckIf(node, refName)) return true;
3788
+ return false;
3789
+ }
3790
+ function isNullCheckOperator(operator) {
3791
+ return operator === "===" || operator === "==" || operator === "!==" || operator === "!=";
3792
+ }
3793
+ /**
3794
+ * Check if a test expression is a null check on `ref.current` for a given ref name.
3795
+ * @param test The test expression to check
3796
+ * @param refName The name of the ref variable (e.g. "myRef") to check against
3797
+ * @returns true if the test is of the form `ref.current === null` or `null === ref.current`
3798
+ */
3799
+ function isRefCurrentNullCheck(test, refName) {
3800
+ if (test.type !== AST_NODE_TYPES.BinaryExpression) return false;
3801
+ if (!isNullCheckOperator(test.operator)) return false;
3802
+ const { left, right } = test;
3803
+ const isRefSide = (side) => side.type === AST_NODE_TYPES.MemberExpression && side.object.type === AST_NODE_TYPES.Identifier && side.object.name === refName && side.property.type === AST_NODE_TYPES.Identifier && side.property.name === "current";
3804
+ const isNullSide = (side) => side.type === AST_NODE_TYPES.Literal && side.value == null;
3805
+ return isRefSide(left) && isNullSide(right) || isRefSide(right) && isNullSide(left);
3806
+ }
3807
+ /**
3808
+ * Check if the node is the operand of a `ref.current === null` test inside an IfStatement.
3809
+ * @param node The MemberExpression node for ref.current
3810
+ * @returns true if the node is part of a null check test in an if statement
3811
+ */
3812
+ function isInNullCheckTest(node) {
3813
+ const { parent } = node;
3814
+ if (parent.type !== AST_NODE_TYPES.BinaryExpression) return false;
3815
+ if (!isNullCheckOperator(parent.operator)) return false;
3816
+ const otherSide = parent.left === node ? parent.right : parent.left;
3817
+ if (otherSide.type !== AST_NODE_TYPES.Literal || otherSide.value != null) return false;
3818
+ return parent.parent.type === AST_NODE_TYPES.IfStatement && parent.parent.test === parent;
3819
+ }
3820
+ /**
3821
+ * Walk up from the node to find a containing IfStatement whose test is a null-check
3822
+ * on `ref.current` with the given ref name.
3823
+ * @param node The MemberExpression node for ref.current
3824
+ * @param refName The name of the ref variable (e.g. "myRef") to check against
3825
+ * @returns the enclosing IfStatement node if found, or null if not found
3826
+ */
3827
+ function findEnclosingRefNullCheckIf(node, refName) {
3828
+ let current = node.parent;
3829
+ while (current != null) {
3830
+ if (current.type === AST_NODE_TYPES.IfStatement) return isRefCurrentNullCheck(current.test, refName) ? current : null;
3831
+ switch (current.type) {
3832
+ case AST_NODE_TYPES.ExpressionStatement:
3833
+ case AST_NODE_TYPES.BlockStatement:
3834
+ case AST_NODE_TYPES.ReturnStatement:
3835
+ case AST_NODE_TYPES.JSXExpressionContainer:
3836
+ case AST_NODE_TYPES.JSXElement:
3837
+ case AST_NODE_TYPES.JSXOpeningElement:
3838
+ case AST_NODE_TYPES.JSXClosingElement:
3839
+ case AST_NODE_TYPES.AssignmentExpression:
3840
+ case AST_NODE_TYPES.VariableDeclaration:
3841
+ case AST_NODE_TYPES.VariableDeclarator:
3842
+ case AST_NODE_TYPES.MemberExpression:
3843
+ case AST_NODE_TYPES.ChainExpression:
3844
+ case AST_NODE_TYPES.CallExpression: break;
3845
+ default: return null;
3846
+ }
3847
+ current = current.parent;
3848
+ }
3849
+ return null;
3850
+ }
3851
+ /**
3852
+ * Check if a write to `ref.current` comes after a sibling if-statement that null-checks
3853
+ * the same ref (inverted lazy init with early return pattern):
3854
+ *
3855
+ * if (ref.current !== null) { return ...; }
3856
+ * ref.current = value; // ← this write
3857
+ * @param node The MemberExpression node for ref.current being written to
3858
+ * @param refName The name of the ref variable (e.g. "myRef") to check against
3859
+ * @returns true if there is a preceding sibling if-statement that null-checks the same ref
3860
+ */
3861
+ function isWriteAfterNullCheckIf(node, refName) {
3862
+ let stmt = node;
3863
+ while (stmt.parent != null && stmt.parent.type !== AST_NODE_TYPES.BlockStatement) stmt = stmt.parent;
3864
+ if (stmt.parent?.type !== AST_NODE_TYPES.BlockStatement) return false;
3865
+ const block = stmt.parent;
3866
+ const stmtIdx = block.body.indexOf(stmt);
3867
+ if (stmtIdx < 0) return false;
3868
+ for (let i = stmtIdx - 1; i >= 0; i--) {
3869
+ const sibling = block.body[i];
3870
+ if (sibling == null) continue;
3871
+ if (sibling.type === AST_NODE_TYPES.IfStatement && isRefCurrentNullCheck(sibling.test, refName)) return true;
3872
+ }
3873
+ return false;
3874
+ }
3875
+ var refs_default = createRule({
3876
+ meta: {
3877
+ type: "problem",
3878
+ docs: { description: "Validates correct usage of refs by checking that 'ref.current' is not read or written during render." },
3879
+ messages: {
3880
+ readDuringRender: "Do not read 'ref.current' during render. Refs are not available during rendering and their values may be stale or inconsistent. Move this read into an effect or event handler.",
3881
+ writeDuringRender: "Do not write to 'ref.current' during render. Refs should only be mutated in effects or event handlers. Move this write into an effect or event handler."
3882
+ },
3883
+ schema: []
3884
+ },
3885
+ name: RULE_NAME$6,
3886
+ create: create$6,
3887
+ defaultOptions: []
3888
+ });
3889
+ function create$6(context) {
3890
+ const hCollector = core.useHookCollector(context);
3891
+ const cCollector = core.useComponentCollector(context);
3892
+ const refAccesses = [];
3893
+ const jsxRefIdentifiers = /* @__PURE__ */ new Set();
3894
+ function isRefIdentifier(node) {
3895
+ if (node.type !== AST_NODE_TYPES.Identifier) return false;
3896
+ if (core.isRefLikeName(node.name)) return true;
3897
+ if (jsxRefIdentifiers.has(node.name)) return true;
3898
+ return core.isInitializedFromRef(node.name, context.sourceCode.getScope(node));
3899
+ }
3900
+ return defineRuleListener(hCollector.visitor, cCollector.visitor, {
3901
+ JSXAttribute(node) {
3902
+ if (node.name.type === AST_NODE_TYPES.JSXIdentifier && node.name.name === "ref" && node.value?.type === AST_NODE_TYPES.JSXExpressionContainer && node.value.expression.type === AST_NODE_TYPES.Identifier) jsxRefIdentifiers.add(node.value.expression.name);
3903
+ },
3904
+ MemberExpression(node) {
3905
+ if (node.property.type !== AST_NODE_TYPES.Identifier || node.property.name !== "current") return;
3906
+ refAccesses.push({
3907
+ node,
3908
+ isWrite: isWriteAccess(node)
3909
+ });
3910
+ },
3911
+ "Program:exit"(program) {
3912
+ const components = cCollector.ctx.getAllComponents(program);
3913
+ const hooks = hCollector.ctx.getAllHooks(program);
3914
+ const componentAndHookFns = new Set([...components.map((c) => c.node), ...hooks.map((h) => h.node)]);
3915
+ const isComponentOrHookFn = (n) => ast.isFunction(n) && componentAndHookFns.has(n);
3916
+ for (const { node, isWrite } of refAccesses) {
3917
+ if (!isRefIdentifier(node.object)) continue;
3918
+ const boundary = ast.findParentNode(node, isComponentOrHookFn);
3919
+ if (boundary == null) continue;
3920
+ if (isInsideNestedFunction(node, boundary)) continue;
3921
+ if (isPartOfLazyInitialization(node, isWrite)) continue;
3922
+ context.report({
3923
+ messageId: isWrite ? "writeDuringRender" : "readDuringRender",
3924
+ node
3925
+ });
3926
+ }
3927
+ }
3928
+ });
3929
+ }
3930
+
3765
3931
  //#endregion
3766
3932
  //#region src/rules/rules-of-hooks.ts
3767
- const RULE_NAME$2 = "rules-of-hooks";
3933
+ const RULE_NAME$5 = "rules-of-hooks";
3768
3934
  var rules_of_hooks_default = createRule({
3769
3935
  meta: {
3770
3936
  type: "problem",
@@ -3782,8 +3948,8 @@ var rules_of_hooks_default = createRule({
3782
3948
  },
3783
3949
  schema: []
3784
3950
  },
3785
- name: RULE_NAME$2,
3786
- create: create$2,
3951
+ name: RULE_NAME$5,
3952
+ create: create$5,
3787
3953
  defaultOptions: []
3788
3954
  });
3789
3955
  function getHookName(node) {
@@ -3818,7 +3984,7 @@ function isLoopNode(node) {
3818
3984
  function isTryCatchNode(node) {
3819
3985
  return node.type === AST_NODE_TYPES.TryStatement;
3820
3986
  }
3821
- function create$2(context) {
3987
+ function create$5(context) {
3822
3988
  const functionStack = [];
3823
3989
  function findEnclosingComponentOrHook() {
3824
3990
  for (let i = functionStack.length - 1; i >= 0; i--) {
@@ -3826,6 +3992,7 @@ function create$2(context) {
3826
3992
  if (entry == null) continue;
3827
3993
  if (entry.kind === "component" || entry.kind === "hook") return entry;
3828
3994
  }
3995
+ return unit;
3829
3996
  }
3830
3997
  function checkHookCall(node) {
3831
3998
  const hookName = getHookName(node);
@@ -3934,7 +4101,7 @@ function create$2(context) {
3934
4101
  return;
3935
4102
  }
3936
4103
  }
3937
- return {
4104
+ return defineRuleListener({
3938
4105
  ":function"(node) {
3939
4106
  const kind = getFunctionEntryKind(node);
3940
4107
  functionStack.push({
@@ -3966,24 +4133,24 @@ function create$2(context) {
3966
4133
  const idx = body.indexOf(stmt);
3967
4134
  if (idx !== -1 && idx < body.length - 1) entry.hasEarlyReturn = true;
3968
4135
  }
3969
- };
4136
+ });
3970
4137
  }
3971
4138
 
3972
4139
  //#endregion
3973
4140
  //#region src/rules/set-state-in-effect.ts
3974
- const RULE_NAME$1 = "set-state-in-effect";
4141
+ const RULE_NAME$4 = "set-state-in-effect";
3975
4142
  var set_state_in_effect_default = createRule({
3976
4143
  meta: {
3977
4144
  type: "problem",
3978
- 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." },
4145
+ docs: { description: "Validates against setting state synchronously in an effect, which can lead to re-renders that degrade performance." },
3979
4146
  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." },
3980
4147
  schema: []
3981
4148
  },
3982
- name: RULE_NAME$1,
3983
- create: create$1,
4149
+ name: RULE_NAME$4,
4150
+ create: create$4,
3984
4151
  defaultOptions: []
3985
4152
  });
3986
- function create$1(context) {
4153
+ function create$4(context) {
3987
4154
  if (!/use\w*Effect/u.test(context.sourceCode.text)) return {};
3988
4155
  const { additionalStateHooks } = getSettingsFromContext(context);
3989
4156
  const functionEntries = [];
@@ -4028,7 +4195,7 @@ function create$1(context) {
4028
4195
  }
4029
4196
  }
4030
4197
  function isIdFromUseStateCall(topLevelId, at) {
4031
- const variableNode = getVariableDefinitionNode(findVariable(topLevelId, context.sourceCode.getScope(topLevelId)), 0);
4198
+ const variableNode = getVariableInitializer(findVariable(topLevelId, context.sourceCode.getScope(topLevelId)), 0);
4032
4199
  if (variableNode == null) return false;
4033
4200
  if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
4034
4201
  if (!isUseStateCall(variableNode)) return false;
@@ -4056,7 +4223,18 @@ function create$1(context) {
4056
4223
  default: return false;
4057
4224
  }
4058
4225
  }
4059
- return {
4226
+ function isHookDecl(node) {
4227
+ if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
4228
+ if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
4229
+ const init = node.init;
4230
+ if (init == null || init.type !== AST_NODE_TYPES.CallExpression) return false;
4231
+ switch (init.callee.type) {
4232
+ case AST_NODE_TYPES.Identifier: return core.isHookName(init.callee.name);
4233
+ case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && core.isHookName(init.callee.property.name);
4234
+ default: return false;
4235
+ }
4236
+ }
4237
+ return defineRuleListener({
4060
4238
  ":function"(node) {
4061
4239
  const kind = getFunctionKind(node);
4062
4240
  functionEntries.push({
@@ -4079,15 +4257,31 @@ function create$1(context) {
4079
4257
  case entry.kind === "deferred":
4080
4258
  case entry.node.async: break;
4081
4259
  case entry.node === setupFunction:
4082
- case entry.kind === "immediate" && ast.findParentNode(entry.node, ast.isFunction) === setupFunction:
4260
+ case entry.kind === "immediate" && ast.findParentNode(entry.node, ast.isFunction) === setupFunction: {
4261
+ const args0 = node.arguments.at(0);
4262
+ if (args0 == null) return;
4263
+ function isArgumentUsingRefValue(context, node) {
4264
+ const isUsingRefValue = (n) => {
4265
+ switch (n.type) {
4266
+ case AST_NODE_TYPES.Identifier: return core.isInitializedFromRef(n.name, context.sourceCode.getScope(n));
4267
+ case AST_NODE_TYPES.MemberExpression: return isUsingRefValue(n.object);
4268
+ case AST_NODE_TYPES.CallExpression: return isUsingRefValue(n.callee) || ast.getNestedIdentifiers(n).some(isUsingRefValue);
4269
+ default: return false;
4270
+ }
4271
+ };
4272
+ if (isUsingRefValue(node)) return true;
4273
+ return ast.isFunction(node) && context.sourceCode.getScope(node.body).references.some((r) => isUsingRefValue(r.identifier));
4274
+ }
4275
+ if (isArgumentUsingRefValue(context, args0)) return;
4083
4276
  context.report({
4084
4277
  messageId: "default",
4085
4278
  node,
4086
4279
  data: { name: context.sourceCode.getText(node.callee) }
4087
4280
  });
4088
4281
  return;
4282
+ }
4089
4283
  default: {
4090
- const init = ast.findParentNode(node, isVariableDeclaratorFromHookCall)?.init;
4284
+ const init = ast.findParentNode(node, isHookDecl)?.init;
4091
4285
  if (init == null) getOrElseUpdate(setStateCallsByFn, entry.node, () => []).push(node);
4092
4286
  else getOrElseUpdate(setStateInHookCallbacks, init, () => []).push(node);
4093
4287
  }
@@ -4108,14 +4302,14 @@ function create$1(context) {
4108
4302
  const parent = node.parent.parent;
4109
4303
  if (parent.type !== AST_NODE_TYPES.CallExpression) break;
4110
4304
  if (!core.isUseMemoCall(parent)) break;
4111
- const init = ast.findParentNode(parent, isVariableDeclaratorFromHookCall)?.init;
4305
+ const init = ast.findParentNode(parent, isHookDecl)?.init;
4112
4306
  if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
4113
4307
  break;
4114
4308
  }
4115
4309
  case AST_NODE_TYPES.CallExpression:
4116
4310
  if (node !== node.parent.arguments.at(0)) break;
4117
4311
  if (core.isUseCallbackCall(node.parent)) {
4118
- const init = ast.findParentNode(node.parent, isVariableDeclaratorFromHookCall)?.init;
4312
+ const init = ast.findParentNode(node.parent, isHookDecl)?.init;
4119
4313
  if (init != null) getOrElseUpdate(setStateInEffectArg, init, () => []).push(node);
4120
4314
  break;
4121
4315
  }
@@ -4124,7 +4318,7 @@ function create$1(context) {
4124
4318
  },
4125
4319
  "Program:exit"() {
4126
4320
  const getSetStateCalls = (id, initialScope) => {
4127
- const node = getVariableDefinitionNode(findVariable(id, initialScope), 0);
4321
+ const node = getVariableInitializer(findVariable(id, initialScope), 0);
4128
4322
  switch (node?.type) {
4129
4323
  case AST_NODE_TYPES.ArrowFunctionExpression:
4130
4324
  case AST_NODE_TYPES.FunctionDeclaration:
@@ -4157,25 +4351,12 @@ function create$1(context) {
4157
4351
  });
4158
4352
  }
4159
4353
  }
4160
- };
4161
- }
4162
- function isInitFromHookCall(init) {
4163
- if (init?.type !== AST_NODE_TYPES.CallExpression) return false;
4164
- switch (init.callee.type) {
4165
- case AST_NODE_TYPES.Identifier: return core.isHookName(init.callee.name);
4166
- case AST_NODE_TYPES.MemberExpression: return init.callee.property.type === AST_NODE_TYPES.Identifier && core.isHookName(init.callee.property.name);
4167
- default: return false;
4168
- }
4169
- }
4170
- function isVariableDeclaratorFromHookCall(node) {
4171
- if (node.type !== AST_NODE_TYPES.VariableDeclarator) return false;
4172
- if (node.id.type !== AST_NODE_TYPES.Identifier) return false;
4173
- return isInitFromHookCall(node.init);
4354
+ });
4174
4355
  }
4175
4356
 
4176
4357
  //#endregion
4177
4358
  //#region src/rules/set-state-in-render.ts
4178
- const RULE_NAME = "set-state-in-render";
4359
+ const RULE_NAME$3 = "set-state-in-render";
4179
4360
  var set_state_in_render_default = createRule({
4180
4361
  meta: {
4181
4362
  type: "problem",
@@ -4183,11 +4364,11 @@ var set_state_in_render_default = createRule({
4183
4364
  messages: { default: "Do not call the 'set' function '{{name}}' unconditionally during render. This will trigger an infinite render loop." },
4184
4365
  schema: []
4185
4366
  },
4186
- name: RULE_NAME,
4187
- create,
4367
+ name: RULE_NAME$3,
4368
+ create: create$3,
4188
4369
  defaultOptions: []
4189
4370
  });
4190
- function create(context) {
4371
+ function create$3(context) {
4191
4372
  const { additionalStateHooks } = getSettingsFromContext(context);
4192
4373
  const functionEntries = [];
4193
4374
  const componentFnRef = { current: null };
@@ -4196,7 +4377,7 @@ function create(context) {
4196
4377
  return core.isUseStateLikeCall(node, additionalStateHooks);
4197
4378
  }
4198
4379
  function isIdFromUseStateCall(topLevelId, at) {
4199
- const variableNode = getVariableDefinitionNode(findVariable(topLevelId, context.sourceCode.getScope(topLevelId)), 0);
4380
+ const variableNode = getVariableInitializer(findVariable(topLevelId, context.sourceCode.getScope(topLevelId)), 0);
4200
4381
  if (variableNode == null) return false;
4201
4382
  if (variableNode.type !== AST_NODE_TYPES.CallExpression) return false;
4202
4383
  if (!isUseStateCall(variableNode)) return false;
@@ -4247,20 +4428,20 @@ function create(context) {
4247
4428
  }
4248
4429
  return false;
4249
4430
  }
4250
- function isComponentLikeFunction(node) {
4431
+ function isComponentOrHookLikeFunction(node) {
4251
4432
  const id = ast.getFunctionId(node);
4252
4433
  if (id == null) return false;
4253
- if (id.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.name);
4254
- if (id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.property.name);
4434
+ if (id.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.name) || core.isHookName(id.name);
4435
+ if (id.type === AST_NODE_TYPES.MemberExpression && id.property.type === AST_NODE_TYPES.Identifier) return core.isComponentName(id.property.name) || core.isHookName(id.property.name);
4255
4436
  return false;
4256
4437
  }
4257
4438
  function getFunctionKind(node) {
4258
- if (isComponentLikeFunction(node)) return "component";
4439
+ if (isComponentOrHookLikeFunction(node)) return "component";
4259
4440
  const parent = ast.findParentNode(node, not(ast.isTypeExpression)) ?? node.parent;
4260
4441
  if (parent.type === AST_NODE_TYPES.CallExpression && parent.callee !== node) return "callback";
4261
4442
  return "other";
4262
4443
  }
4263
- return {
4444
+ return defineRuleListener({
4264
4445
  ":function"(node) {
4265
4446
  const kind = getFunctionKind(node);
4266
4447
  functionEntries.push({
@@ -4307,7 +4488,260 @@ function create(context) {
4307
4488
  const idx = body.indexOf(stmt);
4308
4489
  if (idx !== -1 && idx < body.length - 1) componentHasEarlyReturn.current = true;
4309
4490
  }
4310
- };
4491
+ });
4492
+ }
4493
+
4494
+ //#endregion
4495
+ //#region src/rules/unsupported-syntax.ts
4496
+ const RULE_NAME$2 = "unsupported-syntax";
4497
+ var unsupported_syntax_default = createRule({
4498
+ meta: {
4499
+ type: "problem",
4500
+ docs: { description: "Validates against syntax that React Compiler does not support." },
4501
+ messages: {
4502
+ eval: "Do not use 'eval' inside components or hooks. 'eval' cannot be statically analyzed and is not supported by React Compiler.",
4503
+ iife: "Do not use immediately-invoked function expressions in JSX. IIFEs will not be optimized by React Compiler.",
4504
+ with: "Do not use 'with' statements inside components or hooks. 'with' changes scope dynamically and is not supported by React Compiler."
4505
+ },
4506
+ schema: []
4507
+ },
4508
+ name: RULE_NAME$2,
4509
+ create: create$2,
4510
+ defaultOptions: []
4511
+ });
4512
+ function isEvalCall(node) {
4513
+ return node.callee.type === AST_NODE_TYPES.Identifier && node.callee.name === "eval";
4514
+ }
4515
+ function isIifeCall(node) {
4516
+ return node.parent.type === AST_NODE_TYPES.CallExpression && node.parent.callee === node;
4517
+ }
4518
+ function create$2(context) {
4519
+ const hCollector = core.useHookCollector(context);
4520
+ const cCollector = core.useComponentCollector(context);
4521
+ const evalCalls = [];
4522
+ const withStmts = [];
4523
+ return defineRuleListener(hCollector.visitor, cCollector.visitor, {
4524
+ CallExpression(node) {
4525
+ if (!isEvalCall(node)) return;
4526
+ const func = ast.findParentNode(node, ast.isFunction);
4527
+ if (func == null) return;
4528
+ evalCalls.push({
4529
+ node,
4530
+ func
4531
+ });
4532
+ },
4533
+ "JSXElement :function"(node) {
4534
+ if (isIifeCall(node)) context.report({
4535
+ messageId: "iife",
4536
+ node: node.parent
4537
+ });
4538
+ },
4539
+ "JSXFragment :function"(node) {
4540
+ if (isIifeCall(node)) context.report({
4541
+ messageId: "iife",
4542
+ node: node.parent
4543
+ });
4544
+ },
4545
+ "Program:exit"(node) {
4546
+ const components = cCollector.ctx.getAllComponents(node);
4547
+ const hooks = hCollector.ctx.getAllHooks(node);
4548
+ const funcs = [...components, ...hooks];
4549
+ for (const { node, func } of evalCalls) {
4550
+ if (!funcs.some((f) => f.node === func)) continue;
4551
+ context.report({
4552
+ messageId: "eval",
4553
+ node
4554
+ });
4555
+ }
4556
+ for (const { node, func } of withStmts) {
4557
+ if (!funcs.some((f) => f.node === func)) continue;
4558
+ context.report({
4559
+ messageId: "with",
4560
+ node
4561
+ });
4562
+ }
4563
+ },
4564
+ WithStatement(node) {
4565
+ const func = ast.findParentNode(node, ast.isFunction);
4566
+ if (func == null) return;
4567
+ withStmts.push({
4568
+ node,
4569
+ func
4570
+ });
4571
+ }
4572
+ });
4573
+ }
4574
+
4575
+ //#endregion
4576
+ //#region src/rules/use-memo.ts
4577
+ const RULE_NAME$1 = "use-memo";
4578
+ var use_memo_default = createRule({
4579
+ meta: {
4580
+ type: "problem",
4581
+ docs: { description: "Validates that 'useMemo' is called with a callback that returns a value." },
4582
+ messages: {
4583
+ missingReturnValue: "The callback passed to 'useMemo' must return a value. Without a return value, 'useMemo' always returns 'undefined', which defeats its purpose.",
4584
+ notAssignedToVariable: "The return value of 'useMemo' must be assigned to a variable. Calling 'useMemo' without capturing its return value is likely a mistake — use 'useEffect' for side effects instead."
4585
+ },
4586
+ schema: []
4587
+ },
4588
+ name: RULE_NAME$1,
4589
+ create: create$1,
4590
+ defaultOptions: []
4591
+ });
4592
+ function create$1(context) {
4593
+ if (!context.sourceCode.text.includes("useMemo")) return {};
4594
+ return defineRuleListener({ CallExpression(node) {
4595
+ if (!core.isUseMemoCall(node)) return;
4596
+ const parent = node.parent;
4597
+ if (!(parent.type === AST_NODE_TYPES.VariableDeclarator || parent.type === AST_NODE_TYPES.AssignmentExpression || parent.type === AST_NODE_TYPES.AssignmentPattern || parent.type === AST_NODE_TYPES.Property || parent.type === AST_NODE_TYPES.ReturnStatement || parent.type === AST_NODE_TYPES.JSXExpressionContainer || parent.type === AST_NODE_TYPES.CallExpression || parent.type === AST_NODE_TYPES.NewExpression || parent.type === AST_NODE_TYPES.ArrayExpression || parent.type === AST_NODE_TYPES.ConditionalExpression || parent.type === AST_NODE_TYPES.LogicalExpression || parent.type === AST_NODE_TYPES.SequenceExpression || parent.type === AST_NODE_TYPES.SpreadElement || parent.type === AST_NODE_TYPES.TemplateLiteral || parent.type === AST_NODE_TYPES.BinaryExpression || parent.type === AST_NODE_TYPES.UnaryExpression || parent.type === AST_NODE_TYPES.MemberExpression || parent.type === AST_NODE_TYPES.TaggedTemplateExpression || parent.type === AST_NODE_TYPES.ChainExpression)) {
4598
+ context.report({
4599
+ messageId: "notAssignedToVariable",
4600
+ node
4601
+ });
4602
+ return;
4603
+ }
4604
+ const [callbackArg] = node.arguments;
4605
+ if (callbackArg == null) return;
4606
+ if (!ast.isFunction(callbackArg)) return;
4607
+ if (callbackArg.type === AST_NODE_TYPES.ArrowFunctionExpression && callbackArg.body.type !== AST_NODE_TYPES.BlockStatement) return;
4608
+ if (callbackArg.body.type !== AST_NODE_TYPES.BlockStatement) return;
4609
+ const returnStatements = ast.getNestedReturnStatements(callbackArg);
4610
+ if (returnStatements.length === 0) {
4611
+ context.report({
4612
+ messageId: "missingReturnValue",
4613
+ node: callbackArg
4614
+ });
4615
+ return;
4616
+ }
4617
+ if (!returnStatements.some((stmt) => stmt.argument != null)) context.report({
4618
+ messageId: "missingReturnValue",
4619
+ node: callbackArg
4620
+ });
4621
+ } });
4622
+ }
4623
+
4624
+ //#endregion
4625
+ //#region src/rules/use-state.ts
4626
+ const RULE_NAME = "use-state";
4627
+ const defaultOptions = [{
4628
+ enforceAssignment: true,
4629
+ enforceLazyInitialization: true,
4630
+ enforceSetterName: true
4631
+ }];
4632
+ const schema = [{
4633
+ type: "object",
4634
+ additionalProperties: false,
4635
+ properties: {
4636
+ enforceAssignment: {
4637
+ type: "boolean",
4638
+ default: true
4639
+ },
4640
+ enforceLazyInitialization: {
4641
+ type: "boolean",
4642
+ default: true
4643
+ },
4644
+ enforceSetterName: {
4645
+ type: "boolean",
4646
+ default: true
4647
+ }
4648
+ }
4649
+ }];
4650
+ const LAZY_INIT_ALLOW_LIST = [
4651
+ "Boolean",
4652
+ "String",
4653
+ "Number"
4654
+ ];
4655
+ var use_state_default = createRule({
4656
+ meta: {
4657
+ type: "suggestion",
4658
+ docs: { description: "Enforces correct usage of 'useState', including destructuring, symmetric naming of the value and setter, and wrapping expensive initializers in a lazy initializer function." },
4659
+ messages: {
4660
+ invalidAssignment: "useState should be destructured into a value and setter pair, e.g., const [state, setState] = useState(...).",
4661
+ invalidInitialization: "To prevent re-computation, consider using lazy initial state for useState calls that involve function calls. Ex: 'useState(() => getValue())'.",
4662
+ invalidSetterName: "The setter should be named 'set' followed by the capitalized state variable name, e.g., 'setState' for 'state'."
4663
+ },
4664
+ schema
4665
+ },
4666
+ name: RULE_NAME,
4667
+ create,
4668
+ defaultOptions
4669
+ });
4670
+ function create(context) {
4671
+ if (!context.sourceCode.text.includes("useState")) return {};
4672
+ const { enforceAssignment = true, enforceLazyInitialization = true, enforceSetterName = true } = context.options[0] ?? defaultOptions[0];
4673
+ return defineRuleListener({ CallExpression(node) {
4674
+ if (!core.isUseStateCall(node)) return;
4675
+ if (enforceLazyInitialization) {
4676
+ const [useStateInput] = node.arguments;
4677
+ if (useStateInput != null) {
4678
+ for (const expr of ast.getNestedNewExpressions(useStateInput)) {
4679
+ if (!("name" in expr.callee)) continue;
4680
+ if (LAZY_INIT_ALLOW_LIST.includes(expr.callee.name)) continue;
4681
+ if (ast.findParentNode(expr, core.isUseCall) != null) continue;
4682
+ context.report({
4683
+ messageId: "invalidInitialization",
4684
+ node: expr
4685
+ });
4686
+ }
4687
+ for (const expr of ast.getNestedCallExpressions(useStateInput)) {
4688
+ if (!("name" in expr.callee)) continue;
4689
+ if (core.isHookName(expr.callee.name)) continue;
4690
+ if (LAZY_INIT_ALLOW_LIST.includes(expr.callee.name)) continue;
4691
+ if (ast.findParentNode(expr, core.isUseCall) != null) continue;
4692
+ context.report({
4693
+ messageId: "invalidInitialization",
4694
+ node: expr
4695
+ });
4696
+ }
4697
+ }
4698
+ }
4699
+ if (node.parent.type !== AST_NODE_TYPES.VariableDeclarator) {
4700
+ if (!enforceAssignment) return;
4701
+ context.report({
4702
+ messageId: "invalidAssignment",
4703
+ node
4704
+ });
4705
+ return;
4706
+ }
4707
+ const id = findEnclosingAssignmentTarget(node);
4708
+ if (id?.type !== AST_NODE_TYPES.ArrayPattern) {
4709
+ if (!enforceAssignment) return;
4710
+ context.report({
4711
+ messageId: "invalidAssignment",
4712
+ node: id ?? node
4713
+ });
4714
+ return;
4715
+ }
4716
+ const [value, setter] = id.elements;
4717
+ if (value == null) {
4718
+ if (!enforceAssignment) return;
4719
+ context.report({
4720
+ messageId: "invalidAssignment",
4721
+ node: id
4722
+ });
4723
+ return;
4724
+ }
4725
+ if (setter == null || !enforceSetterName) return;
4726
+ if (value.type !== AST_NODE_TYPES.Identifier) {
4727
+ context.report({
4728
+ messageId: "invalidAssignment",
4729
+ node: value
4730
+ });
4731
+ return;
4732
+ }
4733
+ if (setter.type !== AST_NODE_TYPES.Identifier || !setter.name.startsWith("set")) {
4734
+ context.report({
4735
+ messageId: "invalidSetterName",
4736
+ node: setter
4737
+ });
4738
+ return;
4739
+ }
4740
+ if (snakeCase(setter.name) !== `set_${snakeCase(value.name)}`) context.report({
4741
+ messageId: "invalidSetterName",
4742
+ node: setter
4743
+ });
4744
+ } });
4311
4745
  }
4312
4746
 
4313
4747
  //#endregion
@@ -4325,7 +4759,6 @@ const plugin = {
4325
4759
  "jsx-key-before-spread": jsx_key_before_spread_default,
4326
4760
  "jsx-no-comment-textnodes": jsx_no_comment_textnodes_default,
4327
4761
  "jsx-no-duplicate-props": jsx_no_duplicate_props_default,
4328
- "jsx-no-iife": jsx_no_iife_default,
4329
4762
  "jsx-no-undef": jsx_no_undef_default,
4330
4763
  "jsx-shorthand-boolean": jsx_shorthand_boolean_default,
4331
4764
  "jsx-shorthand-fragment": jsx_shorthand_fragment_default,
@@ -4378,11 +4811,14 @@ const plugin = {
4378
4811
  "prefer-destructuring-assignment": prefer_destructuring_assignment_default,
4379
4812
  "prefer-namespace-import": prefer_namespace_import_default,
4380
4813
  "prefer-read-only-props": prefer_read_only_props_default,
4381
- "prefer-use-state-lazy-initialization": prefer_use_state_lazy_initialization_default,
4382
4814
  purity: purity_default,
4815
+ refs: refs_default,
4383
4816
  "rules-of-hooks": rules_of_hooks_default,
4384
4817
  "set-state-in-effect": set_state_in_effect_default,
4385
- "set-state-in-render": set_state_in_render_default
4818
+ "set-state-in-render": set_state_in_render_default,
4819
+ "unsupported-syntax": unsupported_syntax_default,
4820
+ "use-memo": use_memo_default,
4821
+ "use-state": use_state_default
4386
4822
  }
4387
4823
  };
4388
4824
 
@@ -4432,11 +4868,13 @@ const rules$6 = {
4432
4868
  "react-x/no-unsafe-component-will-update": "warn",
4433
4869
  "react-x/no-use-context": "warn",
4434
4870
  "react-x/no-useless-forward-ref": "warn",
4435
- "react-x/prefer-use-state-lazy-initialization": "warn",
4436
4871
  "react-x/purity": "warn",
4437
4872
  "react-x/rules-of-hooks": "error",
4438
4873
  "react-x/set-state-in-effect": "warn",
4439
- "react-x/set-state-in-render": "error"
4874
+ "react-x/set-state-in-render": "error",
4875
+ "react-x/unsupported-syntax": "error",
4876
+ "react-x/use-memo": "error",
4877
+ "react-x/use-state": "warn"
4440
4878
  };
4441
4879
  const plugins$5 = { "react-x": plugin };
4442
4880
  const settings$5 = { "react-x": DEFAULT_ESLINT_REACT_SETTINGS };
@@ -4497,7 +4935,6 @@ var strict_exports = /* @__PURE__ */ __exportAll({
4497
4935
  const name$2 = "react-x/strict";
4498
4936
  const rules$2 = {
4499
4937
  ...rules$6,
4500
- "react-x/jsx-no-iife": "error",
4501
4938
  "react-x/no-children-prop": "error",
4502
4939
  "react-x/no-class-component": "error",
4503
4940
  "react-x/no-misused-capture-owner-stack": "error",