@eslint-react/core 5.6.2 → 5.6.3-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +109 -2
- package/dist/index.js +186 -6
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -315,7 +315,7 @@ type FunctionSemanticNode = ClientFunctionSemanticNode | ServerFunctionSemanticN
|
|
|
315
315
|
* @param node - The function node to analyze.
|
|
316
316
|
* @returns The identifier node if found, `null` otherwise.
|
|
317
317
|
*/
|
|
318
|
-
declare function getFunctionId(node: TSESTree.Expression | TSESTreeFunction): TSESTree.ArrayExpression | TSESTree.ArrayPattern | TSESTree.ArrowFunctionExpression | TSESTree.AssignmentExpression | TSESTree.AwaitExpression | TSESTree.PrivateInExpression | TSESTree.SymmetricBinaryExpression | TSESTree.CallExpression | TSESTree.ChainExpression | TSESTree.ClassExpression | TSESTree.ConditionalExpression | TSESTree.FunctionExpression | TSESTree.Identifier | TSESTree.ImportExpression | TSESTree.JSXElement | TSESTree.JSXFragment | TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral | TSESTree.LogicalExpression | TSESTree.MemberExpressionComputedName | TSESTree.MemberExpressionNonComputedName | TSESTree.MetaProperty | TSESTree.NewExpression | TSESTree.ObjectExpression | TSESTree.ObjectPattern | TSESTree.
|
|
318
|
+
declare function getFunctionId(node: TSESTree.Expression | TSESTreeFunction): TSESTree.ArrayExpression | TSESTree.ArrayPattern | TSESTree.ArrowFunctionExpression | TSESTree.AssignmentExpression | TSESTree.AwaitExpression | TSESTree.PrivateInExpression | TSESTree.SymmetricBinaryExpression | TSESTree.CallExpression | TSESTree.ChainExpression | TSESTree.ClassExpression | TSESTree.ConditionalExpression | TSESTree.FunctionExpression | TSESTree.Identifier | TSESTree.ImportExpression | TSESTree.JSXElement | TSESTree.JSXFragment | TSESTree.BigIntLiteral | TSESTree.BooleanLiteral | TSESTree.NullLiteral | TSESTree.NumberLiteral | TSESTree.RegExpLiteral | TSESTree.StringLiteral | TSESTree.TemplateLiteral | TSESTree.LogicalExpression | TSESTree.MemberExpressionComputedName | TSESTree.MemberExpressionNonComputedName | TSESTree.MetaProperty | TSESTree.NewExpression | TSESTree.ObjectExpression | TSESTree.ObjectPattern | TSESTree.SequenceExpression | TSESTree.Super | TSESTree.TaggedTemplateExpression | TSESTree.ThisExpression | TSESTree.TSAsExpression | TSESTree.TSInstantiationExpression | TSESTree.TSNonNullExpression | TSESTree.TSSatisfiesExpression | TSESTree.TSTypeAssertion | TSESTree.UnaryExpressionBitwiseNot | TSESTree.UnaryExpressionDelete | TSESTree.UnaryExpressionMinus | TSESTree.UnaryExpressionNot | TSESTree.UnaryExpressionPlus | TSESTree.UnaryExpressionTypeof | TSESTree.UnaryExpressionVoid | TSESTree.UpdateExpression | TSESTree.YieldExpression | TSESTree.PrivateIdentifier | null;
|
|
319
319
|
/**
|
|
320
320
|
* Identifies the initialization path of a function node in the AST.
|
|
321
321
|
*
|
|
@@ -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
|
|
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.
|
|
3
|
+
"version": "5.6.3-next.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.
|
|
37
|
-
"@eslint-react/
|
|
38
|
-
"@eslint-react/
|
|
39
|
-
"@eslint-react/
|
|
40
|
-
"@eslint-react/
|
|
36
|
+
"@eslint-react/ast": "5.6.3-next.0",
|
|
37
|
+
"@eslint-react/jsx": "5.6.3-next.0",
|
|
38
|
+
"@eslint-react/shared": "5.6.3-next.0",
|
|
39
|
+
"@eslint-react/var": "5.6.3-next.0",
|
|
40
|
+
"@eslint-react/eslint": "5.6.3-next.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@typescript-eslint/parser": "^8.59.1",
|