@eslint-react/core 4.0.2-beta.2 → 4.0.2-beta.4
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 +12 -12
- package/dist/index.js +30 -17
- package/package.json +6 -6
package/dist/index.d.ts
CHANGED
|
@@ -295,7 +295,7 @@ declare namespace getComponentCollectorLegacy {
|
|
|
295
295
|
};
|
|
296
296
|
}
|
|
297
297
|
/**
|
|
298
|
-
* Get an api and visitor object for the rule to collect class
|
|
298
|
+
* Get an api and visitor object for the rule to collect class components
|
|
299
299
|
* @param context The ESLint rule context
|
|
300
300
|
* @returns The api and visitor of the collector
|
|
301
301
|
*/
|
|
@@ -308,6 +308,7 @@ declare function getComponentCollectorLegacy(context: RuleContext): getComponent
|
|
|
308
308
|
* @returns `true` if the node is a class component, `false` otherwise
|
|
309
309
|
*/
|
|
310
310
|
declare function isClassComponent(node: TSESTree.Node): node is ast.TSESTreeClass;
|
|
311
|
+
declare function isClassComponent(node: TSESTree.Node, context: RuleContext): node is ast.TSESTreeClass;
|
|
311
312
|
/**
|
|
312
313
|
* Check if a node is a React PureComponent
|
|
313
314
|
* @param node The AST node to check
|
|
@@ -376,7 +377,7 @@ declare function isRenderMethodCallback(node: ast.TSESTreeFunction): boolean;
|
|
|
376
377
|
* @param node The node to check
|
|
377
378
|
* @internal
|
|
378
379
|
*/
|
|
379
|
-
declare function
|
|
380
|
+
declare function isThisSetStateCall(node: TSESTree.CallExpression): boolean;
|
|
380
381
|
/**
|
|
381
382
|
* Check whether the given node is an assignment to this.state
|
|
382
383
|
* @param node The node to check
|
|
@@ -439,6 +440,12 @@ declare function isFunctionWithLooseComponentName(context: RuleContext, fn: ast.
|
|
|
439
440
|
* @returns `true` if the node is a call expression for a component wrapper
|
|
440
441
|
*/
|
|
441
442
|
declare function isComponentWrapperCall(context: RuleContext, node: TSESTree.Node): boolean;
|
|
443
|
+
/**
|
|
444
|
+
* Check if the node is a callback function passed to a component wrapper
|
|
445
|
+
* @param context The ESLint rule context
|
|
446
|
+
* @param node The node to check
|
|
447
|
+
* @returns `true` if the node is a callback function passed to a component wrapper
|
|
448
|
+
*/
|
|
442
449
|
/**
|
|
443
450
|
* Check if the node is a call expression for a component wrapper loosely
|
|
444
451
|
* @param context The ESLint rule context
|
|
@@ -520,7 +527,7 @@ interface HookSemanticNode extends SemanticNode {
|
|
|
520
527
|
/** The other hooks called by the hook */
|
|
521
528
|
hookCalls: TSESTree.CallExpression[];
|
|
522
529
|
/** The directives used in the function (ex: "use strict", "use client", etc.) */
|
|
523
|
-
directives:
|
|
530
|
+
directives: ast.TSESTreeDirective[];
|
|
524
531
|
}
|
|
525
532
|
//#endregion
|
|
526
533
|
//#region src/hook/hook-collector.d.ts
|
|
@@ -553,20 +560,13 @@ declare function isHookId(id: TSESTree.Node): id is TSESTree.Identifier | TSESTr
|
|
|
553
560
|
* @param node The function node to check
|
|
554
561
|
* @returns True if the function is a React Hook, false otherwise
|
|
555
562
|
*/
|
|
556
|
-
declare function
|
|
563
|
+
declare function isHookDefinition(node: ast.TSESTreeFunction | null): boolean;
|
|
557
564
|
/**
|
|
558
565
|
* Check if the given node is a React Hook call by its name.
|
|
559
566
|
* @param node The node to check.
|
|
560
567
|
* @returns `true` if the node is a React Hook call, `false` otherwise.
|
|
561
568
|
*/
|
|
562
569
|
declare function isHookCall(node: TSESTree.Node | null): node is TSESTree.CallExpression;
|
|
563
|
-
/**
|
|
564
|
-
* Check if a node is a call to a specific React hook.
|
|
565
|
-
* Returns a function that accepts a hook name to check against.
|
|
566
|
-
* @param node The AST node to check
|
|
567
|
-
* @returns A function that takes a hook name and returns boolean
|
|
568
|
-
*/
|
|
569
|
-
declare function isHookCallWithName(node: TSESTree.Node | null): (name: string) => boolean;
|
|
570
570
|
/**
|
|
571
571
|
* Detect useEffect calls and variations (useLayoutEffect, etc.) using a regex pattern
|
|
572
572
|
* @param node The AST node to check
|
|
@@ -611,4 +611,4 @@ declare const REACT_BUILTIN_HOOK_NAMES: readonly ["use", "useActionState", "useC
|
|
|
611
611
|
*/
|
|
612
612
|
declare function isHookName(name: string): boolean;
|
|
613
613
|
//#endregion
|
|
614
|
-
export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint, ComponentFlag, ComponentSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, FunctionComponentSemanticNode, FunctionKind, FunctionSemanticNode, HookSemanticNode, REACT_BUILTIN_HOOK_NAMES, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, findImportSource, getComponentCollector, getComponentCollectorLegacy, getComponentFlagFromInitPath, getFunctionComponentId, getHookCollector, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate,
|
|
614
|
+
export { ClassComponentSemanticNode, ClientFunctionSemanticNode, ComponentDetectionHint, ComponentFlag, ComponentSemanticNode, DEFAULT_COMPONENT_DETECTION_HINT, FunctionComponentSemanticNode, FunctionKind, FunctionSemanticNode, HookSemanticNode, REACT_BUILTIN_HOOK_NAMES, SemanticFunc, SemanticNode, ServerFunctionSemanticNode, findImportSource, getComponentCollector, getComponentCollectorLegacy, getComponentFlagFromInitPath, getFunctionComponentId, getHookCollector, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHookCall, isHookDefinition, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRender, isRenderMethodCallback, isRenderMethodLike, isShouldComponentUpdate, isThisSetStateCall, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStoreCall, isUseTransitionCall };
|
package/dist/index.js
CHANGED
|
@@ -185,13 +185,18 @@ function getRequireExpressionArguments(node) {
|
|
|
185
185
|
* @returns The import source or null if not found
|
|
186
186
|
*/
|
|
187
187
|
function findImportSource(name, initialScope) {
|
|
188
|
+
return findImportSourceImpl(name, initialScope, /* @__PURE__ */ new Set());
|
|
189
|
+
}
|
|
190
|
+
function findImportSourceImpl(name, initialScope, visited) {
|
|
191
|
+
if (visited.has(name)) return null;
|
|
192
|
+
visited.add(name);
|
|
188
193
|
const latestDef = findVariable(initialScope, name)?.defs.at(-1);
|
|
189
194
|
if (latestDef == null) return null;
|
|
190
195
|
const { node, parent } = latestDef;
|
|
191
196
|
if (node.type === AST_NODE_TYPES.VariableDeclarator && node.init != null) {
|
|
192
197
|
const { init } = node;
|
|
193
|
-
if (init.type === AST_NODE_TYPES.MemberExpression && init.object.type === AST_NODE_TYPES.Identifier) return
|
|
194
|
-
if (init.type === AST_NODE_TYPES.Identifier) return
|
|
198
|
+
if (init.type === AST_NODE_TYPES.MemberExpression && init.object.type === AST_NODE_TYPES.Identifier) return findImportSourceImpl(init.object.name, initialScope, visited);
|
|
199
|
+
if (init.type === AST_NODE_TYPES.Identifier) return findImportSourceImpl(init.name, initialScope, visited);
|
|
195
200
|
const arg0 = getRequireExpressionArguments(init)?.[0];
|
|
196
201
|
if (arg0 == null || !ast.isLiteral(arg0, "string")) return null;
|
|
197
202
|
return arg0.value;
|
|
@@ -243,7 +248,7 @@ function isReactAPI(api) {
|
|
|
243
248
|
const getText = (n) => context.sourceCode.getText(n);
|
|
244
249
|
const name = ast.getFullyQualifiedName(node, getText);
|
|
245
250
|
if (name === api) return true;
|
|
246
|
-
if (name.
|
|
251
|
+
if (name.endsWith(`.${api}`)) return true;
|
|
247
252
|
return false;
|
|
248
253
|
};
|
|
249
254
|
return dual(2, func);
|
|
@@ -328,7 +333,7 @@ function isHookName(name) {
|
|
|
328
333
|
* @param node The function node to check
|
|
329
334
|
* @returns True if the function is a React Hook, false otherwise
|
|
330
335
|
*/
|
|
331
|
-
function
|
|
336
|
+
function isHookDefinition(node) {
|
|
332
337
|
if (node == null) return false;
|
|
333
338
|
const id = ast.getFunctionId(node);
|
|
334
339
|
switch (id?.type) {
|
|
@@ -507,17 +512,19 @@ function getHookCollector(context) {
|
|
|
507
512
|
|
|
508
513
|
//#endregion
|
|
509
514
|
//#region src/component/component-detection-legacy.ts
|
|
510
|
-
|
|
511
|
-
* Check if a node is a React class component
|
|
512
|
-
* @param node The AST node to check
|
|
513
|
-
* @returns `true` if the node is a class component, `false` otherwise
|
|
514
|
-
*/
|
|
515
|
-
function isClassComponent(node) {
|
|
515
|
+
function isClassComponent(node, context) {
|
|
516
516
|
if ("superClass" in node && node.superClass != null) {
|
|
517
517
|
const re = /^(?:Pure)?Component$/u;
|
|
518
518
|
switch (true) {
|
|
519
|
-
case node.superClass.type === AST_NODE_TYPES.Identifier:
|
|
520
|
-
|
|
519
|
+
case node.superClass.type === AST_NODE_TYPES.Identifier:
|
|
520
|
+
if (!re.test(node.superClass.name)) return false;
|
|
521
|
+
if (context == null) return true;
|
|
522
|
+
return isInitializedFromReact(node.superClass.name, context.sourceCode.getScope(node), "react");
|
|
523
|
+
case node.superClass.type === AST_NODE_TYPES.MemberExpression && node.superClass.property.type === AST_NODE_TYPES.Identifier:
|
|
524
|
+
if (!re.test(node.superClass.property.name)) return false;
|
|
525
|
+
if (context == null) return true;
|
|
526
|
+
if (node.superClass.object.type === AST_NODE_TYPES.Identifier) return isInitializedFromReact(node.superClass.object.name, context.sourceCode.getScope(node), "react");
|
|
527
|
+
return true;
|
|
521
528
|
}
|
|
522
529
|
}
|
|
523
530
|
return false;
|
|
@@ -592,7 +599,7 @@ function isComponentWillUnmountCallback(node) {
|
|
|
592
599
|
* @returns `true` if node is a render function, `false` if not
|
|
593
600
|
*/
|
|
594
601
|
function isRenderMethodLike(node) {
|
|
595
|
-
return ast.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name.startsWith("render") && node.parent.parent
|
|
602
|
+
return ast.isMethodOrProperty(node) && node.key.type === AST_NODE_TYPES.Identifier && node.key.name.startsWith("render") && ast.isOneOf([AST_NODE_TYPES.ClassDeclaration, AST_NODE_TYPES.ClassExpression])(node.parent.parent);
|
|
596
603
|
}
|
|
597
604
|
/**
|
|
598
605
|
* Check if the given node is a function within a render method of a class component
|
|
@@ -617,7 +624,7 @@ function isRenderMethodCallback(node) {
|
|
|
617
624
|
* @param node The node to check
|
|
618
625
|
* @internal
|
|
619
626
|
*/
|
|
620
|
-
function
|
|
627
|
+
function isThisSetStateCall(node) {
|
|
621
628
|
const { callee } = node;
|
|
622
629
|
return callee.type === AST_NODE_TYPES.MemberExpression && ast.isThisExpressionLoose(callee.object) && callee.property.type === AST_NODE_TYPES.Identifier && callee.property.name === "setState";
|
|
623
630
|
}
|
|
@@ -644,6 +651,12 @@ function isComponentWrapperCall(context, node) {
|
|
|
644
651
|
return isMemoCall(context, node) || isForwardRefCall(context, node);
|
|
645
652
|
}
|
|
646
653
|
/**
|
|
654
|
+
* Check if the node is a callback function passed to a component wrapper
|
|
655
|
+
* @param context The ESLint rule context
|
|
656
|
+
* @param node The node to check
|
|
657
|
+
* @returns `true` if the node is a callback function passed to a component wrapper
|
|
658
|
+
*/
|
|
659
|
+
/**
|
|
647
660
|
* Check if the node is a call expression for a component wrapper loosely
|
|
648
661
|
* @param context The ESLint rule context
|
|
649
662
|
* @param node The node to check
|
|
@@ -852,7 +865,7 @@ function getComponentCollector(context, options = {}) {
|
|
|
852
865
|
const initPath = ast.getFunctionInitPath(node);
|
|
853
866
|
const directives = ast.getFunctionDirectives(node);
|
|
854
867
|
const entry = {
|
|
855
|
-
id
|
|
868
|
+
id,
|
|
856
869
|
key,
|
|
857
870
|
kind: "component",
|
|
858
871
|
name,
|
|
@@ -925,7 +938,7 @@ function getComponentCollector(context, options = {}) {
|
|
|
925
938
|
//#region src/component/component-collector-legacy.ts
|
|
926
939
|
const idGen = new IdGenerator("class-component:");
|
|
927
940
|
/**
|
|
928
|
-
* Get an api and visitor object for the rule to collect class
|
|
941
|
+
* Get an api and visitor object for the rule to collect class components
|
|
929
942
|
* @param context The ESLint rule context
|
|
930
943
|
* @returns The api and visitor of the collector
|
|
931
944
|
*/
|
|
@@ -963,4 +976,4 @@ function getComponentCollectorLegacy(context) {
|
|
|
963
976
|
}
|
|
964
977
|
|
|
965
978
|
//#endregion
|
|
966
|
-
export { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, REACT_BUILTIN_HOOK_NAMES, findImportSource, getComponentCollector, getComponentCollectorLegacy, getComponentFlagFromInitPath, getFunctionComponentId, getHookCollector, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate,
|
|
979
|
+
export { ComponentDetectionHint, ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, REACT_BUILTIN_HOOK_NAMES, findImportSource, getComponentCollector, getComponentCollectorLegacy, getComponentFlagFromInitPath, getFunctionComponentId, getHookCollector, isAssignmentToThisState, isCaptureOwnerStack, isCaptureOwnerStackCall, isChildrenCount, isChildrenCountCall, isChildrenForEach, isChildrenForEachCall, isChildrenMap, isChildrenMapCall, isChildrenOnly, isChildrenOnlyCall, isChildrenToArray, isChildrenToArrayCall, isClassComponent, isCloneElement, isCloneElementCall, isComponentDefinition, isComponentDidCatch, isComponentDidMount, isComponentDidMountCallback, isComponentDidUpdate, isComponentName, isComponentNameLoose, isComponentWillMount, isComponentWillReceiveProps, isComponentWillUnmount, isComponentWillUnmountCallback, isComponentWillUpdate, isComponentWrapperCall, isComponentWrapperCallLoose, isComponentWrapperCallback, isComponentWrapperCallbackLoose, isCreateContext, isCreateContextCall, isCreateElement, isCreateElementCall, isCreateRef, isCreateRefCall, isForwardRef, isForwardRefCall, isFunctionWithLooseComponentName, isGetChildContext, isGetDefaultProps, isGetDerivedStateFromError, isGetDerivedStateFromProps, isGetInitialState, isGetSnapshotBeforeUpdate, isHookCall, isHookDefinition, isHookId, isHookName, isInitializedFromReact, isInitializedFromReactNative, isLazy, isLazyCall, isMemo, isMemoCall, isPureComponent, isReactAPI, isReactAPICall, isRender, isRenderMethodCallback, isRenderMethodLike, isShouldComponentUpdate, isThisSetStateCall, isUnsafeComponentWillMount, isUnsafeComponentWillReceiveProps, isUnsafeComponentWillUpdate, isUseActionStateCall, isUseCall, isUseCallbackCall, isUseContextCall, isUseDebugValueCall, isUseDeferredValueCall, isUseEffectCall, isUseEffectCleanupCallback, isUseEffectLikeCall, isUseEffectSetupCallback, isUseFormStatusCall, isUseIdCall, isUseImperativeHandleCall, isUseInsertionEffectCall, isUseLayoutEffectCall, isUseMemoCall, isUseOptimisticCall, isUseReducerCall, isUseRefCall, isUseStateCall, isUseStateLikeCall, isUseSyncExternalStoreCall, isUseTransitionCall };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eslint-react/core",
|
|
3
|
-
"version": "4.0.2-beta.
|
|
3
|
+
"version": "4.0.2-beta.4",
|
|
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": {
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"@typescript-eslint/types": "^8.57.2",
|
|
35
35
|
"@typescript-eslint/utils": "^8.57.2",
|
|
36
36
|
"ts-pattern": "^5.9.0",
|
|
37
|
-
"@eslint-react/ast": "4.0.2-beta.
|
|
38
|
-
"@eslint-react/
|
|
39
|
-
"@eslint-react/var": "4.0.2-beta.
|
|
40
|
-
"@eslint-react/
|
|
37
|
+
"@eslint-react/ast": "4.0.2-beta.4",
|
|
38
|
+
"@eslint-react/shared": "4.0.2-beta.4",
|
|
39
|
+
"@eslint-react/var": "4.0.2-beta.4",
|
|
40
|
+
"@eslint-react/jsx": "4.0.2-beta.4"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"tsdown": "^0.21.
|
|
43
|
+
"tsdown": "^0.21.7",
|
|
44
44
|
"@local/configs": "0.0.0",
|
|
45
45
|
"@local/eff": "3.0.0-beta.72"
|
|
46
46
|
},
|