@@ -31,6 +31,8 @@ export default createRule('prefer-svelte-reactivity', {
3131 ]
3232 } ,
3333 create ( context ) {
34+ const returnedVariables : Map < TSESTree . FunctionDeclaration , TSESTree . VariableDeclarator [ ] > =
35+ new Map ( ) ;
3436 const exportedVars : TSESTree . Node [ ] = [ ] ;
3537 return {
3638 ...( getSvelteContext ( context ) ?. svelteFileType === '.svelte.[js|ts]' && {
@@ -59,6 +61,28 @@ export default createRule('prefer-svelte-reactivity', {
5961 }
6062 }
6163 } ) ,
64+ Identifier ( node ) {
65+ const enclosingReturn = findEnclosingReturn ( node ) ;
66+ if ( enclosingReturn === null ) {
67+ return ;
68+ }
69+ const enclosingFunction = findEnclosingFunction ( enclosingReturn ) ;
70+ if ( enclosingFunction === null ) {
71+ return ;
72+ }
73+ const variable = findVariable ( context , node ) ;
74+ if (
75+ variable === null ||
76+ variable . identifiers . length < 1 ||
77+ variable . identifiers [ 0 ] . parent . type !== 'VariableDeclarator'
78+ ) {
79+ return ;
80+ }
81+ if ( ! returnedVariables . has ( enclosingFunction ) ) {
82+ returnedVariables . set ( enclosingFunction , [ ] ) ;
83+ }
84+ returnedVariables . get ( enclosingFunction ) ?. push ( variable . identifiers [ 0 ] . parent ) ;
85+ } ,
6286 'Program:exit' ( ) {
6387 const referenceTracker = new ReferenceTracker ( context . sourceCode . scopeManager . globalScope ! ) ;
6488 for ( const { node, path } of referenceTracker . iterateGlobalReferences ( {
@@ -96,6 +120,20 @@ export default createRule('prefer-svelte-reactivity', {
96120 } ) ;
97121 }
98122 }
123+ for ( const returnedVar of Array . from ( returnedVariables . values ( ) ) . flat ( ) ) {
124+ if ( isIn ( node , returnedVar ) ) {
125+ context . report ( {
126+ messageId,
127+ node
128+ } ) ;
129+ }
130+ }
131+ if ( findEnclosingReturn ( node ) !== null ) {
132+ context . report ( {
133+ messageId,
134+ node
135+ } ) ;
136+ }
99137 if ( path [ 0 ] === 'Date' && isDateMutable ( referenceTracker , node as TSESTree . Expression ) ) {
100138 context . report ( {
101139 messageId : 'mutableDateUsed' ,
@@ -135,6 +173,24 @@ export default createRule('prefer-svelte-reactivity', {
135173 }
136174} ) ;
137175
176+ function findAncestorOfType < T > ( node : TSESTree . Node , type : T ) : ( TSESTree . Node & { type : T } ) | null {
177+ if ( node . type === type ) {
178+ return node as TSESTree . Node & { type : T } ;
179+ }
180+ if ( node . parent === undefined || node . parent === null ) {
181+ return null ;
182+ }
183+ return findAncestorOfType ( node . parent , type ) ;
184+ }
185+
186+ function findEnclosingReturn ( node : TSESTree . Node ) : TSESTree . ReturnStatement | null {
187+ return findAncestorOfType ( node , 'ReturnStatement' ) ;
188+ }
189+
190+ function findEnclosingFunction ( node : TSESTree . Node ) : TSESTree . FunctionDeclaration | null {
191+ return findAncestorOfType ( node , 'FunctionDeclaration' ) ;
192+ }
193+
138194function isDateMutable ( referenceTracker : ReferenceTracker , ctorNode : TSESTree . Expression ) : boolean {
139195 return ! referenceTracker
140196 . iteratePropertyReferences ( ctorNode , {
0 commit comments