@@ -10,6 +10,8 @@ import type {
10
10
Node ,
11
11
ObjectProperty ,
12
12
Program ,
13
+ SwitchCase ,
14
+ SwitchStatement ,
13
15
} from '@babel/types'
14
16
import { walk } from 'estree-walker'
15
17
@@ -80,14 +82,31 @@ export function walkIdentifiers(
80
82
markScopeIdentifier ( node , id , knownIds ) ,
81
83
)
82
84
}
85
+ } else if ( node . type === 'SwitchStatement' ) {
86
+ if ( node . scopeIds ) {
87
+ node . scopeIds . forEach ( id => markKnownIds ( id , knownIds ) )
88
+ } else {
89
+ // record switch case block-level local variables
90
+ walkSwitchStatement ( node , false , id =>
91
+ markScopeIdentifier ( node , id , knownIds ) ,
92
+ )
93
+ }
83
94
} else if ( node . type === 'CatchClause' && node . param ) {
84
- for ( const id of extractIdentifiers ( node . param ) ) {
85
- markScopeIdentifier ( node , id , knownIds )
95
+ if ( node . scopeIds ) {
96
+ node . scopeIds . forEach ( id => markKnownIds ( id , knownIds ) )
97
+ } else {
98
+ for ( const id of extractIdentifiers ( node . param ) ) {
99
+ markScopeIdentifier ( node , id , knownIds )
100
+ }
86
101
}
87
102
} else if ( isForStatement ( node ) ) {
88
- walkForStatement ( node , false , id =>
89
- markScopeIdentifier ( node , id , knownIds ) ,
90
- )
103
+ if ( node . scopeIds ) {
104
+ node . scopeIds . forEach ( id => markKnownIds ( id , knownIds ) )
105
+ } else {
106
+ walkForStatement ( node , false , id =>
107
+ markScopeIdentifier ( node , id , knownIds ) ,
108
+ )
109
+ }
91
110
}
92
111
} ,
93
112
leave ( node : Node & { scopeIds ?: Set < string > } , parent : Node | null ) {
@@ -187,10 +206,11 @@ export function walkFunctionParams(
187
206
}
188
207
189
208
export function walkBlockDeclarations (
190
- block : BlockStatement | Program ,
209
+ block : BlockStatement | SwitchCase | Program ,
191
210
onIdent : ( node : Identifier ) => void ,
192
211
) : void {
193
- for ( const stmt of block . body ) {
212
+ const body = block . type === 'SwitchCase' ? block . consequent : block . body
213
+ for ( const stmt of body ) {
194
214
if ( stmt . type === 'VariableDeclaration' ) {
195
215
if ( stmt . declare ) continue
196
216
for ( const decl of stmt . declarations ) {
@@ -206,6 +226,8 @@ export function walkBlockDeclarations(
206
226
onIdent ( stmt . id )
207
227
} else if ( isForStatement ( stmt ) ) {
208
228
walkForStatement ( stmt , true , onIdent )
229
+ } else if ( stmt . type === 'SwitchStatement' ) {
230
+ walkSwitchStatement ( stmt , true , onIdent )
209
231
}
210
232
}
211
233
}
@@ -239,6 +261,28 @@ function walkForStatement(
239
261
}
240
262
}
241
263
264
+ function walkSwitchStatement (
265
+ stmt : SwitchStatement ,
266
+ isVar : boolean ,
267
+ onIdent : ( id : Identifier ) => void ,
268
+ ) {
269
+ for ( const cs of stmt . cases ) {
270
+ for ( const stmt of cs . consequent ) {
271
+ if (
272
+ stmt . type === 'VariableDeclaration' &&
273
+ ( stmt . kind === 'var' ? isVar : ! isVar )
274
+ ) {
275
+ for ( const decl of stmt . declarations ) {
276
+ for ( const id of extractIdentifiers ( decl . id ) ) {
277
+ onIdent ( id )
278
+ }
279
+ }
280
+ }
281
+ }
282
+ walkBlockDeclarations ( cs , onIdent )
283
+ }
284
+ }
285
+
242
286
export function extractIdentifiers (
243
287
param : Node ,
244
288
nodes : Identifier [ ] = [ ] ,
0 commit comments