1+ import type { _ } from "@eslint-react/eff" ;
12import type { RuleContext } from "@eslint-react/shared" ;
23import { DEFAULT_ESLINT_REACT_SETTINGS , unsafeDecodeSettings } from "@eslint-react/shared" ;
34import type { Scope } from "@typescript-eslint/scope-manager" ;
@@ -9,32 +10,37 @@ import { isInitializedFromReact } from "./is-initialized-from-react";
910const defaultImportSource = DEFAULT_ESLINT_REACT_SETTINGS . importSource ;
1011
1112/* @internal */
12- export function isFromReactLoose ( node : TSESTree . Identifier | TSESTree . MemberExpression , name : string ) {
13- if ( node . type === T . MemberExpression ) {
14- return node . object . type === T . Identifier
15- && node . property . type === T . Identifier
16- && node . property . name === name ;
13+ export function isFromReactLoose ( node : TSESTree . Node | _ , name : string ) {
14+ switch ( node ?. type ) {
15+ case T . Identifier :
16+ return node . name === name ;
17+ case T . MemberExpression :
18+ return node . object . type === T . Identifier
19+ && node . property . type === T . Identifier
20+ && node . property . name === name ;
21+ default :
22+ return false ;
1723 }
18- return node . name === name ;
1924}
2025
2126/* @internal */
2227export function isFromReactStrict (
23- node : TSESTree . Identifier | TSESTree . MemberExpression ,
28+ node : TSESTree . Node | _ ,
2429 name : string ,
2530 importSource : string ,
2631 initialScope : Scope ,
2732) {
28- if ( node . type === T . MemberExpression ) {
29- return node . object . type === T . Identifier
30- && node . property . type === T . Identifier
31- && node . property . name === name
32- && isInitializedFromReact ( node . object . name , importSource , initialScope ) ;
33+ switch ( node ?. type ) {
34+ case T . Identifier :
35+ return node . name === name && isInitializedFromReact ( name , importSource , initialScope ) ;
36+ case T . MemberExpression :
37+ return node . object . type === T . Identifier
38+ && node . property . type === T . Identifier
39+ && node . property . name === name
40+ && isInitializedFromReact ( node . object . name , importSource , initialScope ) ;
41+ default :
42+ return false ;
3343 }
34- if ( node . name === name ) {
35- return isInitializedFromReact ( name , importSource , initialScope ) ;
36- }
37- return false ;
3844}
3945
4046export function isFromReact ( name : string ) {
@@ -45,51 +51,16 @@ export function isFromReact(name: string) {
4551 } ;
4652}
4753
48- /* @internal */
49- export function isFromReactMemberLoose ( node : TSESTree . MemberExpression , memberName : string , name : string ) {
50- const { object, property } = node ;
51- if ( property . type !== T . Identifier || property . name !== name ) return false ;
52- if ( object . type === T . Identifier && object . name === memberName ) return true ;
53- if (
54- object . type === T . MemberExpression
55- && object . object . type === T . Identifier
56- && object . property . type === T . Identifier
57- ) {
58- return object . property . name === memberName ;
59- }
60- return false ;
61- }
62-
63- /* @internal */
64- export function isFromReactMemberStrict (
65- node : TSESTree . MemberExpression ,
66- memberName : string ,
67- name : string ,
68- importSource : string ,
69- initialScope : Scope ,
70- ) {
71- const { object, property } = node ;
72- if ( property . type !== T . Identifier || property . name !== name ) {
73- return false ;
74- }
75- if ( object . type === T . Identifier && object . name === memberName ) {
76- return isInitializedFromReact ( object . name , importSource , initialScope ) ;
77- }
78- if (
79- object . type === T . MemberExpression
80- && object . object . type === T . Identifier
81- && isInitializedFromReact ( object . object . name , importSource , initialScope )
82- && object . property . type === T . Identifier
83- ) {
84- return object . property . name === memberName ;
85- }
86- return false ;
87- }
88-
8954export function isFromReactMember ( memberName : string , name : string ) {
9055 return ( context : RuleContext , node : TSESTree . MemberExpression ) => {
9156 const { importSource = defaultImportSource , skipImportCheck = true } = unsafeDecodeSettings ( context . settings ) ;
92- if ( skipImportCheck ) return isFromReactMemberLoose ( node , memberName , name ) ;
93- return isFromReactMemberStrict ( node , memberName , name , importSource , context . sourceCode . getScope ( node ) ) ;
57+ const { object, property } = node ;
58+ if ( skipImportCheck ) return isFromReactLoose ( object , memberName ) && isFromReactLoose ( property , name ) ;
59+ return isFromReactStrict (
60+ object ,
61+ memberName ,
62+ importSource ,
63+ context . sourceCode . getScope ( object ) ,
64+ ) && isFromReactStrict ( property , name , importSource , context . sourceCode . getScope ( property ) ) ;
9465 } ;
9566}
0 commit comments