@@ -12,12 +12,41 @@ use crate::{marks::Marks, util::is_global_var_with_pure_property_access};
12
12
mod ctx;
13
13
14
14
#[ derive( Default ) ]
15
+ #[ non_exhaustive]
15
16
pub struct AliasConfig {
16
17
pub marks : Option < Marks > ,
17
18
pub ignore_nested : bool ,
18
19
/// TODO(kdy1): This field is used for sequential inliner.
19
20
/// It should be renamed to some correct name.
20
21
pub need_all : bool ,
22
+
23
+ /// We can skip visiting children nodes in some cases.
24
+ ///
25
+ /// Because we recurse in the usage analyzer, we don't need to recurse into
26
+ /// child node that the usage analyzer will invoke [`collect_infects_from`]
27
+ /// on.
28
+ pub ignore_named_child_scope : bool ,
29
+ }
30
+ impl AliasConfig {
31
+ pub fn marks ( mut self , arg : Option < Marks > ) -> Self {
32
+ self . marks = arg;
33
+ self
34
+ }
35
+
36
+ pub fn ignore_nested ( mut self , arg : bool ) -> Self {
37
+ self . ignore_nested = arg;
38
+ self
39
+ }
40
+
41
+ pub fn ignore_named_child_scope ( mut self , arg : bool ) -> Self {
42
+ self . ignore_named_child_scope = arg;
43
+ self
44
+ }
45
+
46
+ pub fn need_all ( mut self , arg : bool ) -> Self {
47
+ self . need_all = arg;
48
+ self
49
+ }
21
50
}
22
51
23
52
pub trait InfectableNode {
@@ -99,8 +128,8 @@ pub struct InfectionCollector<'a> {
99
128
}
100
129
101
130
impl InfectionCollector < ' _ > {
102
- fn add_id ( & mut self , e : & Id ) {
103
- if self . exclude . contains ( e) {
131
+ fn add_id ( & mut self , e : Id ) {
132
+ if self . exclude . contains ( & e) {
104
133
return ;
105
134
}
106
135
@@ -109,7 +138,7 @@ impl InfectionCollector<'_> {
109
138
}
110
139
111
140
self . accesses . insert ( (
112
- e. clone ( ) ,
141
+ e,
113
142
if self . ctx . is_callee {
114
143
AccessKind :: Call
115
144
} else {
@@ -122,6 +151,18 @@ impl InfectionCollector<'_> {
122
151
impl Visit for InfectionCollector < ' _ > {
123
152
noop_visit_type ! ( ) ;
124
153
154
+ fn visit_assign_expr ( & mut self , n : & AssignExpr ) {
155
+ if self . config . ignore_named_child_scope
156
+ && n. op == op ! ( "=" )
157
+ && n. left . as_simple ( ) . and_then ( |l| l. leftmost ( ) ) . is_some ( )
158
+ {
159
+ n. left . visit_with ( self ) ;
160
+ return ;
161
+ }
162
+
163
+ n. visit_children_with ( self ) ;
164
+ }
165
+
125
166
fn visit_bin_expr ( & mut self , e : & BinExpr ) {
126
167
match e. op {
127
168
op ! ( "in" )
@@ -163,6 +204,14 @@ impl Visit for InfectionCollector<'_> {
163
204
}
164
205
}
165
206
207
+ fn visit_callee ( & mut self , n : & Callee ) {
208
+ let ctx = Ctx {
209
+ is_callee : true ,
210
+ ..self . ctx
211
+ } ;
212
+ n. visit_children_with ( & mut * self . with_ctx ( ctx) ) ;
213
+ }
214
+
166
215
fn visit_cond_expr ( & mut self , e : & CondExpr ) {
167
216
{
168
217
let ctx = Ctx {
@@ -183,15 +232,11 @@ impl Visit for InfectionCollector<'_> {
183
232
}
184
233
}
185
234
186
- fn visit_ident ( & mut self , n : & Ident ) {
187
- self . add_id ( & n. to_id ( ) ) ;
188
- }
189
-
190
235
fn visit_expr ( & mut self , e : & Expr ) {
191
236
match e {
192
237
Expr :: Ident ( i) => {
193
238
if self . ctx . track_expr_ident {
194
- self . add_id ( & i. to_id ( ) ) ;
239
+ self . add_id ( i. to_id ( ) ) ;
195
240
}
196
241
}
197
242
@@ -205,6 +250,25 @@ impl Visit for InfectionCollector<'_> {
205
250
}
206
251
}
207
252
253
+ fn visit_fn_decl ( & mut self , n : & FnDecl ) {
254
+ if self . config . ignore_named_child_scope {
255
+ return ;
256
+ }
257
+
258
+ n. visit_children_with ( self ) ;
259
+ }
260
+
261
+ fn visit_fn_expr ( & mut self , n : & FnExpr ) {
262
+ if self . config . ignore_named_child_scope && n. ident . is_some ( ) {
263
+ return ;
264
+ }
265
+ n. visit_children_with ( self ) ;
266
+ }
267
+
268
+ fn visit_ident ( & mut self , n : & Ident ) {
269
+ self . add_id ( n. to_id ( ) ) ;
270
+ }
271
+
208
272
fn visit_member_expr ( & mut self , n : & MemberExpr ) {
209
273
{
210
274
let ctx = Ctx {
@@ -232,6 +296,15 @@ impl Visit for InfectionCollector<'_> {
232
296
}
233
297
}
234
298
299
+ fn visit_prop_name ( & mut self , n : & PropName ) {
300
+ if let PropName :: Computed ( c) = & n {
301
+ c. visit_with ( & mut * self . with_ctx ( Ctx {
302
+ is_callee : false ,
303
+ ..self . ctx
304
+ } ) ) ;
305
+ }
306
+ }
307
+
235
308
fn visit_super_prop_expr ( & mut self , n : & SuperPropExpr ) {
236
309
if let SuperProp :: Computed ( c) = & n. prop {
237
310
c. visit_with ( & mut * self . with_ctx ( Ctx {
@@ -277,20 +350,13 @@ impl Visit for InfectionCollector<'_> {
277
350
e. arg . visit_with ( & mut * self . with_ctx ( ctx) ) ;
278
351
}
279
352
280
- fn visit_prop_name ( & mut self , n : & PropName ) {
281
- if let PropName :: Computed ( c) = & n {
282
- c. visit_with ( & mut * self . with_ctx ( Ctx {
283
- is_callee : false ,
284
- ..self . ctx
285
- } ) ) ;
353
+ fn visit_var_declarator ( & mut self , n : & VarDeclarator ) {
354
+ if self . config . ignore_named_child_scope {
355
+ if let ( Pat :: Ident ( ..) , Some ( ..) ) = ( & n. name , n. init . as_deref ( ) ) {
356
+ return ;
357
+ }
286
358
}
287
- }
288
359
289
- fn visit_callee ( & mut self , n : & Callee ) {
290
- let ctx = Ctx {
291
- is_callee : true ,
292
- ..self . ctx
293
- } ;
294
- n. visit_children_with ( & mut * self . with_ctx ( ctx) ) ;
360
+ n. visit_children_with ( self ) ;
295
361
}
296
362
}
0 commit comments