@@ -46,7 +46,8 @@ export default createRule<[], MessageID>({
4646 if ( ! / u s e \w * E f f e c t / u. test ( context . sourceCode . text ) ) return { } ;
4747 const settings = decodeSettings ( context . settings ) ;
4848 const additionalHooks = settings . additionalHooks ?? { } ;
49- const isUseEffectLikeCall = isReactHookCallWithNameAlias (
49+
50+ const isUseLayoutEffectLikeCall = isReactHookCallWithNameAlias (
5051 "useLayoutEffect" ,
5152 context ,
5253 additionalHooks . useLayoutEffect ?? [ ] ,
@@ -56,32 +57,36 @@ export default createRule<[], MessageID>({
5657 const isUseCallbackCall = isReactHookCallWithNameAlias ( "useCallback" , context , additionalHooks . useCallback ?? [ ] ) ;
5758 const isSetStateCall = isSetFunctionCall ( context , settings ) ;
5859 const isIdFromUseStateCall = isFromUseStateCall ( context , settings ) ;
60+
5961 const functionStack : [ node : AST . TSESTreeFunction , kind : FunctionKind ] [ ] = [ ] ;
6062 const setupFunctionRef = { current : O . none < AST . TSESTreeFunction > ( ) } ;
6163 const setupFunctionIdentifiers : TSESTree . Identifier [ ] = [ ] ;
62- const indirectFunctionCalls : TSESTree . CallExpression [ ] = [ ] ;
63- const indirectSetStateCalls = new WeakMap < AST . TSESTreeFunction , TSESTree . CallExpression [ ] > ( ) ;
64- const indirectSetStateCallsAsArgs = new WeakMap < TSESTree . CallExpression , TSESTree . Identifier [ ] > ( ) ;
65- const indirectSetStateCallsAsSetups = new Map < TSESTree . CallExpression , TSESTree . Identifier [ ] > ( ) ;
66- const indirectSetStateCallsInHooks = new WeakMap <
64+
65+ const indFunctionCalls : TSESTree . CallExpression [ ] = [ ] ;
66+ const indSetStateCalls = new WeakMap < AST . TSESTreeFunction , TSESTree . CallExpression [ ] > ( ) ;
67+ const indSetStateCallsInUseLayoutEffectArg0 = new WeakMap < TSESTree . CallExpression , TSESTree . Identifier [ ] > ( ) ;
68+ const indSetStateCallsInUseLayoutEffectSetup = new Map < TSESTree . CallExpression , TSESTree . Identifier [ ] > ( ) ;
69+ const indSetStateCallsInUseMemoOrCallback = new WeakMap <
6770 TSESTree . VariableDeclarator [ "init" ] & { } ,
6871 TSESTree . CallExpression [ ]
6972 > ( ) ;
73+
7074 const onSetupFunctionEnter = ( node : AST . TSESTreeFunction ) => {
7175 setupFunctionRef . current = O . some ( node ) ;
7276 } ;
7377 const onSetupFunctionExit = ( node : AST . TSESTreeFunction ) => {
7478 setupFunctionRef . current = O . filter ( setupFunctionRef . current , ( current ) => current !== node ) ;
7579 } ;
80+
7681 function isSetupFunction ( node : TSESTree . Node ) {
7782 return node . parent ?. type === AST_NODE_TYPES . CallExpression
7883 && node . parent . callee !== node
79- && isUseEffectLikeCall ( node . parent ) ;
84+ && isUseLayoutEffectLikeCall ( node . parent ) ;
8085 }
8186 function getCallKind ( node : TSESTree . CallExpression ) {
8287 return match < TSESTree . CallExpression , CallKind > ( node )
8388 . when ( isUseStateCall , ( ) => "useState" )
84- . when ( isUseEffectLikeCall , ( ) => "useLayoutEffect" )
89+ . when ( isUseLayoutEffectLikeCall , ( ) => "useLayoutEffect" )
8590 . when ( isSetStateCall , ( ) => "setState" )
8691 . when ( isThenCall , ( ) => "then" )
8792 . otherwise ( ( ) => "other" ) ;
@@ -114,12 +119,12 @@ export default createRule<[], MessageID>({
114119 const maybeVd = AST . traverseUpGuard ( node , isVariableDeclaratorFromHookCall ) ;
115120 if ( O . isSome ( maybeVd ) ) {
116121 const vd = maybeVd . value ;
117- const calls = indirectSetStateCallsInHooks . get ( vd . init ) ?? [ ] ;
118- indirectSetStateCallsInHooks . set ( vd . init , [ ...calls , node ] ) ;
122+ const calls = indSetStateCallsInUseMemoOrCallback . get ( vd . init ) ?? [ ] ;
123+ indSetStateCallsInUseMemoOrCallback . set ( vd . init , [ ...calls , node ] ) ;
119124 return ;
120125 }
121- const calls = indirectSetStateCalls . get ( parentFn ) ?? [ ] ;
122- indirectSetStateCalls . set ( parentFn , [ ...calls , node ] ) ;
126+ const calls = indSetStateCalls . get ( parentFn ) ?? [ ] ;
127+ indSetStateCalls . set ( parentFn , [ ...calls , node ] ) ;
123128 return ;
124129 }
125130 context . report ( {
@@ -138,7 +143,7 @@ export default createRule<[], MessageID>({
138143 . with ( "other" , ( ) => {
139144 const isInSetupFunction = effectFn === parentFn ;
140145 if ( ! isInSetupFunction ) return ;
141- indirectFunctionCalls . push ( node ) ;
146+ indFunctionCalls . push ( node ) ;
142147 } )
143148 . otherwise ( F . constVoid ) ;
144149 } ,
@@ -156,8 +161,8 @@ export default createRule<[], MessageID>({
156161 const maybeVd = AST . traverseUpGuard ( parent , isVariableDeclaratorFromHookCall ) ;
157162 if ( O . isNone ( maybeVd ) ) break ;
158163 const vd = maybeVd . value ;
159- const calls = indirectSetStateCallsAsArgs . get ( vd . init ) ?? [ ] ;
160- indirectSetStateCallsAsArgs . set ( vd . init , [ ...calls , node ] ) ;
164+ const calls = indSetStateCallsInUseLayoutEffectArg0 . get ( vd . init ) ?? [ ] ;
165+ indSetStateCallsInUseLayoutEffectArg0 . set ( vd . init , [ ...calls , node ] ) ;
161166 break ;
162167 }
163168 case AST_NODE_TYPES . CallExpression : {
@@ -170,14 +175,14 @@ export default createRule<[], MessageID>({
170175 const maybeVd = AST . traverseUpGuard ( node . parent , isVariableDeclaratorFromHookCall ) ;
171176 if ( O . isNone ( maybeVd ) ) break ;
172177 const vd = maybeVd . value ;
173- const calls = indirectSetStateCallsAsArgs . get ( vd . init ) ?? [ ] ;
174- indirectSetStateCallsAsArgs . set ( vd . init , [ ...calls , node ] ) ;
178+ const calls = indSetStateCallsInUseLayoutEffectArg0 . get ( vd . init ) ?? [ ] ;
179+ indSetStateCallsInUseLayoutEffectArg0 . set ( vd . init , [ ...calls , node ] ) ;
175180 }
176181 // const [state, setState] = useState();
177182 // useLayoutEffect(setState);
178- if ( isUseEffectLikeCall ( node . parent ) ) {
179- const calls = indirectSetStateCallsAsArgs . get ( node . parent ) ?? [ ] ;
180- indirectSetStateCallsAsSetups . set ( node . parent , [ ...calls , node ] ) ;
183+ if ( isUseLayoutEffectLikeCall ( node . parent ) ) {
184+ const calls = indSetStateCallsInUseLayoutEffectArg0 . get ( node . parent ) ?? [ ] ;
185+ indSetStateCallsInUseLayoutEffectSetup . set ( node . parent , [ ...calls , node ] ) ;
181186 }
182187 break ;
183188 }
@@ -193,13 +198,14 @@ export default createRule<[], MessageID>({
193198 case AST_NODE_TYPES . ArrowFunctionExpression :
194199 case AST_NODE_TYPES . FunctionDeclaration :
195200 case AST_NODE_TYPES . FunctionExpression :
196- return indirectSetStateCalls . get ( node ) ?? [ ] ;
201+ return indSetStateCalls . get ( node ) ?? [ ] ;
197202 case AST_NODE_TYPES . CallExpression :
198- return indirectSetStateCallsInHooks . get ( node ) ?? indirectSetStateCallsAsArgs . get ( node ) ?? [ ] ;
203+ return indSetStateCallsInUseMemoOrCallback . get ( node ) ?? indSetStateCallsInUseLayoutEffectArg0 . get ( node )
204+ ?? [ ] ;
199205 }
200206 return [ ] ;
201207 } ;
202- for ( const [ _ , calls ] of indirectSetStateCallsAsSetups ) {
208+ for ( const [ _ , calls ] of indSetStateCallsInUseLayoutEffectSetup ) {
203209 for ( const call of calls ) {
204210 context . report ( {
205211 messageId : "noDirectSetStateInUseLayoutEffect" ,
@@ -208,7 +214,7 @@ export default createRule<[], MessageID>({
208214 } ) ;
209215 }
210216 }
211- for ( const { callee } of indirectFunctionCalls ) {
217+ for ( const { callee } of indFunctionCalls ) {
212218 if ( ! ( "name" in callee ) ) continue ;
213219 const { name } = callee ;
214220 const setStateCalls = getSetStateCalls ( name , context . sourceCode . getScope ( callee ) ) ;
0 commit comments