@eslint-react/core 5.6.2 → 5.6.3-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -614,6 +614,113 @@ declare namespace getHookCollector {
614
614
  */
615
615
  declare function getHookCollector(context: RuleContext): getHookCollector.ReturnType;
616
616
  //#endregion
617
+ //#region src/jsx.d.ts
618
+ /**
619
+ * BitFlags for configuring JSX detection behavior.
620
+ *
621
+ * Used by {@link isJsxLike} to control which AST node kinds are
622
+ * considered "JSX-like". Combine flags with the `|` operator.
623
+ *
624
+ * @example
625
+ * ```ts
626
+ * const hint = JsxDetectionHint.DoNotIncludeJsxWithBooleanValue
627
+ * | JsxDetectionHint.DoNotIncludeJsxWithStringValue;
628
+ *
629
+ * isJsxLike(context, node, hint);
630
+ * ```
631
+ */
632
+ type JsxDetectionHint = bigint;
633
+ declare const JsxDetectionHint: {
634
+ readonly None: 0n;
635
+ readonly DoNotIncludeJsxWithNullValue: bigint;
636
+ readonly DoNotIncludeJsxWithNumberValue: bigint;
637
+ readonly DoNotIncludeJsxWithBigIntValue: bigint;
638
+ readonly DoNotIncludeJsxWithStringValue: bigint;
639
+ readonly DoNotIncludeJsxWithBooleanValue: bigint;
640
+ readonly DoNotIncludeJsxWithUndefinedValue: bigint;
641
+ readonly DoNotIncludeJsxWithEmptyArrayValue: bigint;
642
+ readonly DoNotIncludeJsxWithCreateElementValue: bigint;
643
+ readonly RequireAllArrayElementsToBeJsx: bigint;
644
+ readonly RequireBothSidesOfLogicalExpressionToBeJsx: bigint;
645
+ readonly RequireBothBranchesOfConditionalExpressionToBeJsx: bigint;
646
+ };
647
+ /**
648
+ * Default JSX detection configuration.
649
+ *
650
+ * Skips number, bigint, boolean, string, and undefined literals –
651
+ * the value types that are commonly returned alongside JSX in React
652
+ * components but are not themselves renderable elements.
653
+ */
654
+ declare const DEFAULT_JSX_DETECTION_HINT: JsxDetectionHint;
655
+ /**
656
+ * Determine whether a node represents JSX-like content based on heuristics.
657
+ *
658
+ * The detection behaviour is configurable through {@link JsxDetectionHint}
659
+ * bit-flags so that callers can opt individual value kinds in or out.
660
+ *
661
+ * @param context - The ESLint rule context (needed for variable resolution).
662
+ * @param node - The AST node to analyse.
663
+ * @param hint - Optional bit-flags to adjust detection behaviour.
664
+ * Defaults to {@link DEFAULT_JSX_DETECTION_HINT}.
665
+ * @returns Whether the node is considered JSX-like.
666
+ *
667
+ * @example
668
+ * ```ts
669
+ * import { isJsxLike } from "@eslint-react/core";
670
+ *
671
+ * if (isJsxLike(context, node)) {
672
+ * // node looks like it evaluates to a React element
673
+ * }
674
+ * ```
675
+ */
676
+ declare function isJsxLike(context: RuleContext, node: TSESTree.Node | null, hint?: JsxDetectionHint): boolean;
677
+ //#endregion
678
+ //#region src/jsx-config.d.ts
679
+ /**
680
+ * Resolved JSX configuration derived from compiler options and / or pragma
681
+ * annotations found in the source file.
682
+ */
683
+ interface JsxConfig {
684
+ jsx?: number;
685
+ jsxFactory?: string;
686
+ jsxFragmentFactory?: string;
687
+ jsxImportSource?: string;
688
+ }
689
+ /**
690
+ * Read JSX configuration from the TypeScript compiler options exposed by the
691
+ * parser services.
692
+ *
693
+ * Falls back to sensible React defaults when no compiler options are
694
+ * available (e.g. when the file is parsed without type information).
695
+ *
696
+ * @param context - The ESLint rule context.
697
+ * @returns Fully‑populated `JsxConfig` derived from compiler options.
698
+ */
699
+ declare function getJsxConfigFromCompilerOptions(context: RuleContext): Required<JsxConfig>;
700
+ /**
701
+ * Extract JSX configuration from `@jsx`, `@jsxFrag`, `@jsxRuntime` and
702
+ * `@jsxImportSource` pragma comments in the source file.
703
+ *
704
+ * The result is cached per `sourceCode` instance via a `WeakMap` so that
705
+ * repeated calls from different rules analysing the same file are free.
706
+ *
707
+ * @param context - The ESLint rule context.
708
+ * @returns Partial `JsxConfig` containing only the values found in pragmas.
709
+ */
710
+ declare function getJsxConfigFromAnnotation(context: RuleContext): JsxConfig;
711
+ /**
712
+ * Get the fully‑merged JSX configuration for the current file.
713
+ *
714
+ * Compiler options provide the base values; pragma annotations found in the
715
+ * source override them where present. The result is cached per `sourceCode`.
716
+ *
717
+ * This is the main entry‑point most consumers should use.
718
+ *
719
+ * @param context - The ESLint rule context.
720
+ * @returns Fully‑populated, merged `JsxConfig`.
721
+ */
722
+ declare function getJsxConfig(context: RuleContext): Required<JsxConfig>;
723
+ //#endregion
617
724
  //#region src/type-is.d.ts
618
725
  declare function isBooleanLiteralType<TType extends ts.Type>(type: TType): type is TType & {
619
726
  intrinsicName: "false" | "true";
@@ -742,4 +849,4 @@ type TypeVariant = "any" | "bigint" | "boolean" | "enum" | "never" | "nullish" |
742
849
  */
743
850
  declare function getTypeVariants(types: ts.Type[]): Set<TypeVariant>;
744
851
  //#endregion
745
- export { ClassComponentSemanticNode, ClientFunctionSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, FunctionComponentDetectionHint, FunctionComponentFlag, FunctionComponentSemanticNode, FunctionDisplayNameAssignment, FunctionID, FunctionInitPath, FunctionKind, FunctionSemanticNode, HookSemanticNode, REACT_BUILTIN_HOOK_NAMES, SEL_FUNCTION_DISPLAY_NAME_ASSIGNMENT, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, TypeVariant, getClassComponentCollector, getClassId, getFullyQualifiedNameEx, getFunctionComponentCollector, getFunctionComponentFlagFromInitPath, getFunctionComponentId, getFunctionDirectives, getFunctionId, getFunctionInitPath, getHookCollector, getTypeVariants, isAPI, isAPICall, isAPIFromReact, isAPIFromReactNative, isAnyType, isAssignmentToThisState, isBigIntType, isBooleanLiteralType, isBooleanType, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isClassComponentLoose, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isEnumType, isFalseLiteralType, isFalsyBigIntType, isFalsyNumberType, isFalsyStringType, isForwardRef, isForwardRefCall, isFunctionComponentDefinition, isFunctionComponentName, isFunctionComponentNameLoose, isFunctionComponentWrapperCall, isFunctionComponentWrapperCallback, isFunctionEmpty, isFunctionHasCallInInitPath, isFunctionHasDirective, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHookCall, isHookDefinition, isHookId, isHookName, isLazy, isLazyCall, isMemo, isMemoCall, isNeverType, isNullishType, isNumberType, isObjectType, isPureComponent, isRender, isRenderMethodCallback, isRenderMethodLike, isShouldComponentUpdate, isStringType, isThisSetStateCall, isTrueLiteralType, isTruthyBigIntType, isTruthyNumberType, isTruthyStringType, isUnknownType, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUse, isUseActionState, isUseActionStateCall, isUseCall, isUseCallback, isUseCallbackCall, isUseContext, isUseContextCall, isUseDebugValue, isUseDebugValueCall, isUseDeferredValue, isUseDeferredValueCall, isUseEffect, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatus, isUseFormStatusCall, isUseId, isUseIdCall, isUseImperativeHandle, isUseImperativeHandleCall, isUseInsertionEffect, isUseInsertionEffectCall, isUseLayoutEffect, isUseLayoutEffectCall, isUseMemo, isUseMemoCall, isUseOptimistic, isUseOptimisticCall, isUseReducer, isUseReducerCall, isUseRef, isUseRefCall, isUseState, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStore, isUseSyncExternalStoreCall, isUseTransition, isUseTransitionCall };
852
+ export { ClassComponentSemanticNode, ClientFunctionSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, FunctionComponentDetectionHint, FunctionComponentFlag, FunctionComponentSemanticNode, FunctionDisplayNameAssignment, FunctionID, FunctionInitPath, FunctionKind, FunctionSemanticNode, HookSemanticNode, JsxConfig, JsxDetectionHint, REACT_BUILTIN_HOOK_NAMES, SEL_FUNCTION_DISPLAY_NAME_ASSIGNMENT, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, TypeVariant, getClassComponentCollector, getClassId, getFullyQualifiedNameEx, getFunctionComponentCollector, getFunctionComponentFlagFromInitPath, getFunctionComponentId, getFunctionDirectives, getFunctionId, getFunctionInitPath, getHookCollector, getJsxConfig, getJsxConfigFromAnnotation, getJsxConfigFromCompilerOptions, getTypeVariants, isAPI, isAPICall, isAPIFromReact, isAPIFromReactNative, isAnyType, isAssignmentToThisState, isBigIntType, isBooleanLiteralType, isBooleanType, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isClassComponentLoose, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isEnumType, isFalseLiteralType, isFalsyBigIntType, isFalsyNumberType, isFalsyStringType, isForwardRef, isForwardRefCall, isFunctionComponentDefinition, isFunctionComponentName, isFunctionComponentNameLoose, isFunctionComponentWrapperCall, isFunctionComponentWrapperCallback, isFunctionEmpty, isFunctionHasCallInInitPath, isFunctionHasDirective, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHookCall, isHookDefinition, isHookId, isHookName, isJsxLike, isLazy, isLazyCall, isMemo, isMemoCall, isNeverType, isNullishType, isNumberType, isObjectType, isPureComponent, isRender, isRenderMethodCallback, isRenderMethodLike, isShouldComponentUpdate, isStringType, isThisSetStateCall, isTrueLiteralType, isTruthyBigIntType, isTruthyNumberType, isTruthyStringType, isUnknownType, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUse, isUseActionState, isUseActionStateCall, isUseCall, isUseCallback, isUseCallbackCall, isUseContext, isUseContextCall, isUseDebugValue, isUseDebugValueCall, isUseDeferredValue, isUseDeferredValueCall, isUseEffect, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatus, isUseFormStatusCall, isUseId, isUseIdCall, isUseImperativeHandle, isUseImperativeHandleCall, isUseInsertionEffect, isUseInsertionEffectCall, isUseLayoutEffect, isUseLayoutEffectCall, isUseMemo, isUseMemoCall, isUseOptimistic, isUseOptimisticCall, isUseReducer, isUseReducerCall, isUseRef, isUseRefCall, isUseState, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStore, isUseSyncExternalStoreCall, isUseTransition, isUseTransitionCall };
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import { Check, Extract, Traverse, is, isOneOf } from "@eslint-react/ast";
2
- import { resolveImportSource } from "@eslint-react/var";
2
+ import { resolve, resolveImportSource } from "@eslint-react/var";
3
3
  import { AST_NODE_TYPES } from "@typescript-eslint/types";
4
4
  import { randomBytes } from "node:crypto";
5
- import { JsxDetectionHint, isJsxLike } from "@eslint-react/jsx";
6
- import { RE_COMPONENT_NAME, RE_COMPONENT_NAME_LOOSE } from "@eslint-react/shared";
7
- import { P, isMatching, match } from "ts-pattern";
5
+ import { JsxDetectionHint as JsxDetectionHint$1 } from "@eslint-react/jsx";
6
+ import { RE_ANNOTATION_JSX, RE_ANNOTATION_JSX_FRAG, RE_ANNOTATION_JSX_IMPORT_SOURCE, RE_ANNOTATION_JSX_RUNTIME, RE_COMPONENT_NAME, RE_COMPONENT_NAME_LOOSE } from "@eslint-react/shared";
8
7
  import ts from "typescript";
8
+ import { P, isMatching, match } from "ts-pattern";
9
9
 
10
10
  //#region ../../.pkgs/eff/dist/index.js
11
11
  /**
@@ -648,7 +648,7 @@ function isFunctionWithLooseComponentName(context, fn, allowNone = false) {
648
648
  * Hints for component collector
649
649
  */
650
650
  const FunctionComponentDetectionHint = {
651
- ...JsxDetectionHint,
651
+ ...JsxDetectionHint$1,
652
652
  DoNotIncludeFunctionDefinedAsClassMethod: 1n << 11n,
653
653
  DoNotIncludeFunctionDefinedAsClassProperty: 1n << 12n,
654
654
  DoNotIncludeFunctionDefinedAsObjectMethod: 1n << 13n,
@@ -848,6 +848,101 @@ function isUseEffectCleanupCallback(node) {
848
848
  return isUseEffectSetupCallback(enclosingFunction);
849
849
  }
850
850
 
851
+ //#endregion
852
+ //#region src/jsx.ts
853
+ const JsxDetectionHint = {
854
+ None: 0n,
855
+ DoNotIncludeJsxWithNullValue: 1n << 0n,
856
+ DoNotIncludeJsxWithNumberValue: 1n << 1n,
857
+ DoNotIncludeJsxWithBigIntValue: 1n << 2n,
858
+ DoNotIncludeJsxWithStringValue: 1n << 3n,
859
+ DoNotIncludeJsxWithBooleanValue: 1n << 4n,
860
+ DoNotIncludeJsxWithUndefinedValue: 1n << 5n,
861
+ DoNotIncludeJsxWithEmptyArrayValue: 1n << 6n,
862
+ DoNotIncludeJsxWithCreateElementValue: 1n << 7n,
863
+ RequireAllArrayElementsToBeJsx: 1n << 8n,
864
+ RequireBothSidesOfLogicalExpressionToBeJsx: 1n << 9n,
865
+ RequireBothBranchesOfConditionalExpressionToBeJsx: 1n << 10n
866
+ };
867
+ /**
868
+ * Default JSX detection configuration.
869
+ *
870
+ * Skips number, bigint, boolean, string, and undefined literals –
871
+ * the value types that are commonly returned alongside JSX in React
872
+ * components but are not themselves renderable elements.
873
+ */
874
+ const DEFAULT_JSX_DETECTION_HINT = 0n | JsxDetectionHint.DoNotIncludeJsxWithNumberValue | JsxDetectionHint.DoNotIncludeJsxWithBigIntValue | JsxDetectionHint.DoNotIncludeJsxWithBooleanValue | JsxDetectionHint.DoNotIncludeJsxWithStringValue | JsxDetectionHint.DoNotIncludeJsxWithUndefinedValue;
875
+ /**
876
+ * Determine whether a node represents JSX-like content based on heuristics.
877
+ *
878
+ * The detection behaviour is configurable through {@link JsxDetectionHint}
879
+ * bit-flags so that callers can opt individual value kinds in or out.
880
+ *
881
+ * @param context - The ESLint rule context (needed for variable resolution).
882
+ * @param node - The AST node to analyse.
883
+ * @param hint - Optional bit-flags to adjust detection behaviour.
884
+ * Defaults to {@link DEFAULT_JSX_DETECTION_HINT}.
885
+ * @returns Whether the node is considered JSX-like.
886
+ *
887
+ * @example
888
+ * ```ts
889
+ * import { isJsxLike } from "@eslint-react/core";
890
+ *
891
+ * if (isJsxLike(context, node)) {
892
+ * // node looks like it evaluates to a React element
893
+ * }
894
+ * ```
895
+ */
896
+ function isJsxLike(context, node, hint = DEFAULT_JSX_DETECTION_HINT) {
897
+ if (node == null) return false;
898
+ if (Check.isJSX(node)) return true;
899
+ switch (node.type) {
900
+ case AST_NODE_TYPES.Literal:
901
+ switch (typeof node.value) {
902
+ case "boolean": return !(hint & JsxDetectionHint.DoNotIncludeJsxWithBooleanValue);
903
+ case "string": return !(hint & JsxDetectionHint.DoNotIncludeJsxWithStringValue);
904
+ case "number": return !(hint & JsxDetectionHint.DoNotIncludeJsxWithNumberValue);
905
+ case "bigint": return !(hint & JsxDetectionHint.DoNotIncludeJsxWithBigIntValue);
906
+ }
907
+ if (node.value == null) return !(hint & JsxDetectionHint.DoNotIncludeJsxWithNullValue);
908
+ return false;
909
+ case AST_NODE_TYPES.TemplateLiteral: return !(hint & JsxDetectionHint.DoNotIncludeJsxWithStringValue);
910
+ case AST_NODE_TYPES.ArrayExpression:
911
+ if (node.elements.length === 0) return !(hint & JsxDetectionHint.DoNotIncludeJsxWithEmptyArrayValue);
912
+ if (hint & JsxDetectionHint.RequireAllArrayElementsToBeJsx) return node.elements.every((n) => isJsxLike(context, n, hint));
913
+ return node.elements.some((n) => isJsxLike(context, n, hint));
914
+ case AST_NODE_TYPES.LogicalExpression:
915
+ if (hint & JsxDetectionHint.RequireBothSidesOfLogicalExpressionToBeJsx) return isJsxLike(context, node.left, hint) && isJsxLike(context, node.right, hint);
916
+ return isJsxLike(context, node.left, hint) || isJsxLike(context, node.right, hint);
917
+ case AST_NODE_TYPES.ConditionalExpression: {
918
+ const consequentIsJsx = Array.isArray(node.consequent) ? checkArray(context, node.consequent, hint) : isJsxLike(context, node.consequent, hint);
919
+ const alternateIsJsx = isJsxLike(context, node.alternate, hint);
920
+ if (hint & JsxDetectionHint.RequireBothBranchesOfConditionalExpressionToBeJsx) return consequentIsJsx && alternateIsJsx;
921
+ return consequentIsJsx || alternateIsJsx;
922
+ }
923
+ case AST_NODE_TYPES.SequenceExpression: return isJsxLike(context, node.expressions.at(-1) ?? null, hint);
924
+ case AST_NODE_TYPES.CallExpression: {
925
+ if (hint & JsxDetectionHint.DoNotIncludeJsxWithCreateElementValue) return false;
926
+ const callee = Extract.unwrap(node.callee);
927
+ switch (callee.type) {
928
+ case AST_NODE_TYPES.Identifier: return callee.name === "createElement";
929
+ case AST_NODE_TYPES.MemberExpression: return callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "createElement";
930
+ }
931
+ return false;
932
+ }
933
+ case AST_NODE_TYPES.Identifier:
934
+ if (node.name === "undefined") return !(hint & JsxDetectionHint.DoNotIncludeJsxWithUndefinedValue);
935
+ if (Check.isJSXTagNameExpression(node)) return true;
936
+ return isJsxLike(context, resolve(context, node), hint);
937
+ }
938
+ return false;
939
+ }
940
+ function checkArray(context, elements, hint) {
941
+ if (elements.length === 0) return !(hint & JsxDetectionHint.DoNotIncludeJsxWithEmptyArrayValue);
942
+ if (hint & JsxDetectionHint.RequireAllArrayElementsToBeJsx) return elements.every((n) => isJsxLike(context, n, hint));
943
+ return elements.some((n) => isJsxLike(context, n, hint));
944
+ }
945
+
851
946
  //#endregion
852
947
  //#region src/function-component-collector.ts
853
948
  /**
@@ -1005,6 +1100,91 @@ function getHookCollector(context) {
1005
1100
  };
1006
1101
  }
1007
1102
 
1103
+ //#endregion
1104
+ //#region src/jsx-config.ts
1105
+ /**
1106
+ * Weak‑map cache keyed by `sourceCode` so that the (potentially expensive)
1107
+ * pragma‑scanning pass runs at most once per file.
1108
+ */
1109
+ const annotationCache = /* @__PURE__ */ new WeakMap();
1110
+ /**
1111
+ * Weak‑map cache for the fully‑merged config (compiler options + annotation).
1112
+ */
1113
+ const mergedCache = /* @__PURE__ */ new WeakMap();
1114
+ /**
1115
+ * Read JSX configuration from the TypeScript compiler options exposed by the
1116
+ * parser services.
1117
+ *
1118
+ * Falls back to sensible React defaults when no compiler options are
1119
+ * available (e.g. when the file is parsed without type information).
1120
+ *
1121
+ * @param context - The ESLint rule context.
1122
+ * @returns Fully‑populated `JsxConfig` derived from compiler options.
1123
+ */
1124
+ function getJsxConfigFromCompilerOptions(context) {
1125
+ const options = context.sourceCode.parserServices?.program?.getCompilerOptions() ?? {};
1126
+ return {
1127
+ jsx: options.jsx ?? ts.JsxEmit.ReactJSX,
1128
+ jsxFactory: options.jsxFactory ?? "React.createElement",
1129
+ jsxFragmentFactory: options.jsxFragmentFactory ?? "React.Fragment",
1130
+ jsxImportSource: options.jsxImportSource ?? "react"
1131
+ };
1132
+ }
1133
+ /**
1134
+ * Extract JSX configuration from `@jsx`, `@jsxFrag`, `@jsxRuntime` and
1135
+ * `@jsxImportSource` pragma comments in the source file.
1136
+ *
1137
+ * The result is cached per `sourceCode` instance via a `WeakMap` so that
1138
+ * repeated calls from different rules analysing the same file are free.
1139
+ *
1140
+ * @param context - The ESLint rule context.
1141
+ * @returns Partial `JsxConfig` containing only the values found in pragmas.
1142
+ */
1143
+ function getJsxConfigFromAnnotation(context) {
1144
+ const cached = annotationCache.get(context.sourceCode);
1145
+ if (cached != null) return cached;
1146
+ const options = {};
1147
+ if (!context.sourceCode.text.includes("@jsx")) {
1148
+ annotationCache.set(context.sourceCode, options);
1149
+ return options;
1150
+ }
1151
+ let jsx, jsxFrag, jsxRuntime, jsxImportSource;
1152
+ for (const comment of context.sourceCode.getAllComments().reverse()) {
1153
+ const value = comment.value;
1154
+ jsx ??= value.match(RE_ANNOTATION_JSX)?.[1];
1155
+ jsxFrag ??= value.match(RE_ANNOTATION_JSX_FRAG)?.[1];
1156
+ jsxRuntime ??= value.match(RE_ANNOTATION_JSX_RUNTIME)?.[1];
1157
+ jsxImportSource ??= value.match(RE_ANNOTATION_JSX_IMPORT_SOURCE)?.[1];
1158
+ }
1159
+ if (jsx != null) options.jsxFactory = jsx;
1160
+ if (jsxFrag != null) options.jsxFragmentFactory = jsxFrag;
1161
+ if (jsxRuntime != null) options.jsx = jsxRuntime === "classic" ? ts.JsxEmit.React : ts.JsxEmit.ReactJSX;
1162
+ if (jsxImportSource != null) options.jsxImportSource = jsxImportSource;
1163
+ annotationCache.set(context.sourceCode, options);
1164
+ return options;
1165
+ }
1166
+ /**
1167
+ * Get the fully‑merged JSX configuration for the current file.
1168
+ *
1169
+ * Compiler options provide the base values; pragma annotations found in the
1170
+ * source override them where present. The result is cached per `sourceCode`.
1171
+ *
1172
+ * This is the main entry‑point most consumers should use.
1173
+ *
1174
+ * @param context - The ESLint rule context.
1175
+ * @returns Fully‑populated, merged `JsxConfig`.
1176
+ */
1177
+ function getJsxConfig(context) {
1178
+ const cached = mergedCache.get(context.sourceCode);
1179
+ if (cached != null) return cached;
1180
+ const merged = {
1181
+ ...getJsxConfigFromCompilerOptions(context),
1182
+ ...getJsxConfigFromAnnotation(context)
1183
+ };
1184
+ mergedCache.set(context.sourceCode, merged);
1185
+ return merged;
1186
+ }
1187
+
1008
1188
  //#endregion
1009
1189
  //#region src/type-is.ts
1010
1190
  function isFlagSet(allFlags, flag) {
@@ -1152,4 +1332,4 @@ function getTypeVariants(types) {
1152
1332
  }
1153
1333
 
1154
1334
  //#endregion
1155
- export { DEFAULT_COMPONENT_DETECTION_HINT, FunctionComponentDetectionHint, FunctionComponentFlag, REACT_BUILTIN_HOOK_NAMES, SEL_FUNCTION_DISPLAY_NAME_ASSIGNMENT, getClassComponentCollector, getClassId, getFullyQualifiedNameEx, getFunctionComponentCollector, getFunctionComponentFlagFromInitPath, getFunctionComponentId, getFunctionDirectives, getFunctionId, getFunctionInitPath, getHookCollector, getTypeVariants, isAPI, isAPICall, isAPIFromReact, isAPIFromReactNative, isAnyType, isAssignmentToThisState, isBigIntType, isBooleanLiteralType, isBooleanType, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isClassComponentLoose, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isEnumType, isFalseLiteralType, isFalsyBigIntType, isFalsyNumberType, isFalsyStringType, isForwardRef, isForwardRefCall, isFunctionComponentDefinition, isFunctionComponentName, isFunctionComponentNameLoose, isFunctionComponentWrapperCall, isFunctionComponentWrapperCallback, isFunctionEmpty, isFunctionHasCallInInitPath, isFunctionHasDirective, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHookCall, isHookDefinition, isHookId, isHookName, isLazy, isLazyCall, isMemo, isMemoCall, isNeverType, isNullishType, isNumberType, isObjectType, isPureComponent, isRender, isRenderMethodCallback, isRenderMethodLike, isShouldComponentUpdate, isStringType, isThisSetStateCall, isTrueLiteralType, isTruthyBigIntType, isTruthyNumberType, isTruthyStringType, isUnknownType, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUse, isUseActionState, isUseActionStateCall, isUseCall, isUseCallback, isUseCallbackCall, isUseContext, isUseContextCall, isUseDebugValue, isUseDebugValueCall, isUseDeferredValue, isUseDeferredValueCall, isUseEffect, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatus, isUseFormStatusCall, isUseId, isUseIdCall, isUseImperativeHandle, isUseImperativeHandleCall, isUseInsertionEffect, isUseInsertionEffectCall, isUseLayoutEffect, isUseLayoutEffectCall, isUseMemo, isUseMemoCall, isUseOptimistic, isUseOptimisticCall, isUseReducer, isUseReducerCall, isUseRef, isUseRefCall, isUseState, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStore, isUseSyncExternalStoreCall, isUseTransition, isUseTransitionCall };
1335
+ export { DEFAULT_COMPONENT_DETECTION_HINT, DEFAULT_JSX_DETECTION_HINT, FunctionComponentDetectionHint, FunctionComponentFlag, JsxDetectionHint, REACT_BUILTIN_HOOK_NAMES, SEL_FUNCTION_DISPLAY_NAME_ASSIGNMENT, getClassComponentCollector, getClassId, getFullyQualifiedNameEx, getFunctionComponentCollector, getFunctionComponentFlagFromInitPath, getFunctionComponentId, getFunctionDirectives, getFunctionId, getFunctionInitPath, getHookCollector, getJsxConfig, getJsxConfigFromAnnotation, getJsxConfigFromCompilerOptions, getTypeVariants, isAPI, isAPICall, isAPIFromReact, isAPIFromReactNative, isAnyType, isAssignmentToThisState, isBigIntType, isBooleanLiteralType, isBooleanType, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isClassComponentLoose, isCloneElement, isCloneElementCall, isComponentDidCatch, isComponentDidMount, isComponentDidUpdate, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUpdate, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isEnumType, isFalseLiteralType, isFalsyBigIntType, isFalsyNumberType, isFalsyStringType, isForwardRef, isForwardRefCall, isFunctionComponentDefinition, isFunctionComponentName, isFunctionComponentNameLoose, isFunctionComponentWrapperCall, isFunctionComponentWrapperCallback, isFunctionEmpty, isFunctionHasCallInInitPath, isFunctionHasDirective, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHookCall, isHookDefinition, isHookId, isHookName, isJsxLike, isLazy, isLazyCall, isMemo, isMemoCall, isNeverType, isNullishType, isNumberType, isObjectType, isPureComponent, isRender, isRenderMethodCallback, isRenderMethodLike, isShouldComponentUpdate, isStringType, isThisSetStateCall, isTrueLiteralType, isTruthyBigIntType, isTruthyNumberType, isTruthyStringType, isUnknownType, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUse, isUseActionState, isUseActionStateCall, isUseCall, isUseCallback, isUseCallbackCall, isUseContext, isUseContextCall, isUseDebugValue, isUseDebugValueCall, isUseDeferredValue, isUseDeferredValueCall, isUseEffect, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatus, isUseFormStatusCall, isUseId, isUseIdCall, isUseImperativeHandle, isUseImperativeHandleCall, isUseInsertionEffect, isUseInsertionEffectCall, isUseLayoutEffect, isUseLayoutEffectCall, isUseMemo, isUseMemoCall, isUseOptimistic, isUseOptimisticCall, isUseReducer, isUseReducerCall, isUseRef, isUseRefCall, isUseState, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStore, isUseSyncExternalStoreCall, isUseTransition, isUseTransitionCall };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eslint-react/core",
3
- "version": "5.6.2",
3
+ "version": "5.6.3-beta.0",
4
4
  "description": "ESLint React's ESLint utility module for static analysis of React core APIs and patterns.",
5
5
  "homepage": "https://github.com/Rel1cx/eslint-react",
6
6
  "bugs": {
@@ -33,11 +33,11 @@
33
33
  "@typescript-eslint/types": "^8.59.1",
34
34
  "@typescript-eslint/utils": "^8.59.1",
35
35
  "ts-pattern": "^5.9.0",
36
- "@eslint-react/ast": "5.6.2",
37
- "@eslint-react/eslint": "5.6.2",
38
- "@eslint-react/jsx": "5.6.2",
39
- "@eslint-react/shared": "5.6.2",
40
- "@eslint-react/var": "5.6.2"
36
+ "@eslint-react/ast": "5.6.3-beta.0",
37
+ "@eslint-react/eslint": "5.6.3-beta.0",
38
+ "@eslint-react/shared": "5.6.3-beta.0",
39
+ "@eslint-react/var": "5.6.3-beta.0",
40
+ "@eslint-react/jsx": "5.6.3-beta.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@typescript-eslint/parser": "^8.59.1",