@@ -54,6 +54,71 @@ export default createRule('prefer-svelte-reactivity', {
54
54
const returnedFunctionCalls : Map < FunctionLike , TSESTree . MethodDefinition [ ] > = new Map ( ) ;
55
55
const returnedVariables : Map < FunctionLike , VariableLike [ ] > = new Map ( ) ;
56
56
const exportedVars : TSESTree . Node [ ] = [ ] ;
57
+
58
+ function recordReturnedIdentifiers ( node : TSESTree . Identifier | TSESTree . PrivateIdentifier ) {
59
+ function recordVariable ( enclosingFunction : FunctionLike , variable : VariableLike ) : void {
60
+ if ( variable === null ) {
61
+ return ;
62
+ }
63
+ if ( ! returnedVariables . has ( enclosingFunction ) ) {
64
+ returnedVariables . set ( enclosingFunction , [ ] ) ;
65
+ }
66
+ returnedVariables . get ( enclosingFunction ) ?. push ( variable ) ;
67
+ }
68
+
69
+ function recordFunctionCall (
70
+ enclosingFunction : FunctionLike ,
71
+ functionCall : TSESTree . MethodDefinition
72
+ ) : void {
73
+ if ( functionCall === null ) {
74
+ return ;
75
+ }
76
+ if ( ! returnedFunctionCalls . has ( enclosingFunction ) ) {
77
+ returnedFunctionCalls . set ( enclosingFunction , [ ] ) ;
78
+ }
79
+ returnedFunctionCalls . get ( enclosingFunction ) ?. push ( functionCall ) ;
80
+ }
81
+
82
+ const enclosingReturn = findEnclosingReturn ( node ) ;
83
+ if ( enclosingReturn === null ) {
84
+ return ;
85
+ }
86
+ const enclosingFunction = findEnclosingFunction ( enclosingReturn ) ;
87
+ if ( enclosingFunction === null ) {
88
+ return ;
89
+ }
90
+ if ( node . parent . type === 'MemberExpression' ) {
91
+ const enclosingClassBody = findEnclosingClassBody ( node ) ;
92
+ for ( const classElement of enclosingClassBody ?. body ?? [ ] ) {
93
+ if (
94
+ classElement . type === 'PropertyDefinition' &&
95
+ ( classElement . key . type === 'Identifier' ||
96
+ classElement . key . type === 'PrivateIdentifier' ) &&
97
+ node . name === classElement . key . name
98
+ ) {
99
+ recordVariable ( enclosingFunction , classElement ) ;
100
+ }
101
+ if (
102
+ classElement . type === 'MethodDefinition' &&
103
+ ( classElement . key . type === 'Identifier' ||
104
+ classElement . key . type === 'PrivateIdentifier' ) &&
105
+ node . name === classElement . key . name
106
+ ) {
107
+ recordFunctionCall ( enclosingFunction , classElement ) ;
108
+ }
109
+ }
110
+ } else if ( node . type === 'Identifier' ) {
111
+ const variable = findVariable ( context , node ) ;
112
+ if (
113
+ variable !== null &&
114
+ variable . identifiers . length > 0 &&
115
+ variable . identifiers [ 0 ] . parent . type === 'VariableDeclarator'
116
+ ) {
117
+ recordVariable ( enclosingFunction , variable . identifiers [ 0 ] . parent ) ;
118
+ }
119
+ }
120
+ }
121
+
57
122
return {
58
123
...( getSvelteContext ( context ) ?. svelteFileType === '.svelte.[js|ts]' && {
59
124
ExportNamedDeclaration ( node ) {
@@ -81,67 +146,8 @@ export default createRule('prefer-svelte-reactivity', {
81
146
}
82
147
}
83
148
} ) ,
84
- Identifier ( node ) {
85
- function recordVariable ( enclosingFunction : FunctionLike , variable : VariableLike ) : void {
86
- if ( variable === null ) {
87
- return ;
88
- }
89
- if ( ! returnedVariables . has ( enclosingFunction ) ) {
90
- returnedVariables . set ( enclosingFunction , [ ] ) ;
91
- }
92
- returnedVariables . get ( enclosingFunction ) ?. push ( variable ) ;
93
- }
94
-
95
- function recordFunctionCall (
96
- enclosingFunction : FunctionLike ,
97
- functionCall : TSESTree . MethodDefinition
98
- ) : void {
99
- if ( functionCall === null ) {
100
- return ;
101
- }
102
- if ( ! returnedFunctionCalls . has ( enclosingFunction ) ) {
103
- returnedFunctionCalls . set ( enclosingFunction , [ ] ) ;
104
- }
105
- returnedFunctionCalls . get ( enclosingFunction ) ?. push ( functionCall ) ;
106
- }
107
-
108
- const enclosingReturn = findEnclosingReturn ( node ) ;
109
- if ( enclosingReturn === null ) {
110
- return ;
111
- }
112
- const enclosingFunction = findEnclosingFunction ( enclosingReturn ) ;
113
- if ( enclosingFunction === null ) {
114
- return ;
115
- }
116
- if ( node . parent . type === 'MemberExpression' ) {
117
- const enclosingClassBody = findEnclosingClassBody ( node ) ;
118
- for ( const classElement of enclosingClassBody ?. body ?? [ ] ) {
119
- if (
120
- classElement . type === 'PropertyDefinition' &&
121
- classElement . key . type === 'Identifier' &&
122
- node . name === classElement . key . name
123
- ) {
124
- recordVariable ( enclosingFunction , classElement ) ;
125
- }
126
- if (
127
- classElement . type === 'MethodDefinition' &&
128
- classElement . key . type === 'Identifier' &&
129
- node . name === classElement . key . name
130
- ) {
131
- recordFunctionCall ( enclosingFunction , classElement ) ;
132
- }
133
- }
134
- } else {
135
- const variable = findVariable ( context , node ) ;
136
- if (
137
- variable !== null &&
138
- variable . identifiers . length > 0 &&
139
- variable . identifiers [ 0 ] . parent . type === 'VariableDeclarator'
140
- ) {
141
- recordVariable ( enclosingFunction , variable . identifiers [ 0 ] . parent ) ;
142
- }
143
- }
144
- } ,
149
+ Identifier : recordReturnedIdentifiers ,
150
+ PrivateIdentifier : recordReturnedIdentifiers ,
145
151
'Program:exit' ( ) {
146
152
const referenceTracker = new ReferenceTracker ( context . sourceCode . scopeManager . globalScope ! ) ;
147
153
for ( const { node, path } of referenceTracker . iterateGlobalReferences ( {
@@ -320,13 +326,13 @@ function isPropertyEncapsulated(
320
326
returnedFunctionCalls : Map < FunctionLike , TSESTree . MethodDefinition [ ] > ,
321
327
returnedVariables : Map < FunctionLike , VariableLike [ ] >
322
328
) : boolean {
323
- if ( node . accessibility === 'public' ) {
329
+ if ( isPublic ( node ) ) {
324
330
return false ;
325
331
}
326
332
for ( const classElement of node . parent . body ) {
327
333
if (
328
334
classElement . type === 'MethodDefinition' &&
329
- classElement . accessibility === 'public' &&
335
+ isPublic ( classElement ) &&
330
336
methodReturnsProperty ( classElement , node , returnedFunctionCalls , returnedVariables )
331
337
) {
332
338
return false ;
@@ -335,6 +341,13 @@ function isPropertyEncapsulated(
335
341
return true ;
336
342
}
337
343
344
+ function isPublic ( node : TSESTree . MethodDefinition | TSESTree . PropertyDefinition ) : boolean {
345
+ return (
346
+ ( node . accessibility === undefined && node . key . type !== 'PrivateIdentifier' ) ||
347
+ node . accessibility === 'public'
348
+ ) ;
349
+ }
350
+
338
351
function isDateMutable ( referenceTracker : ReferenceTracker , ctorNode : TSESTree . Expression ) : boolean {
339
352
return ! referenceTracker
340
353
. iteratePropertyReferences ( ctorNode , {
0 commit comments