@@ -217,6 +217,20 @@ impl Resolver {
217
217
for prop in n. props . iter_mut ( ) {
218
218
match prop {
219
219
ObjectPatProp :: KeyValue ( p) => {
220
+ if let PropName :: Computed ( key) = & mut p. key {
221
+ struct BindingIdent < ' r > {
222
+ r : & ' r mut Resolver ,
223
+ }
224
+ impl < ' r > VisitMut for BindingIdent < ' r > {
225
+ noop_visit_mut_type ! ( ) ;
226
+
227
+ fn visit_mut_ident ( & mut self , ident : & mut Ident ) {
228
+ self . r . add_binding_for_ident ( ident) ;
229
+ }
230
+ }
231
+ let mut v = BindingIdent { r : self } ;
232
+ key. visit_mut_children_with ( & mut v) ;
233
+ } ;
220
234
self . visit_pat_with_binding ( & mut p. value , is_var) ;
221
235
}
222
236
ObjectPatProp :: Assign ( p) => {
@@ -247,67 +261,6 @@ impl Resolver {
247
261
}
248
262
}
249
263
250
- fn lookahead_hoist_stmt ( & mut self , stmt : & mut Stmt ) {
251
- let Stmt :: Decl ( decl) = stmt else {
252
- return ;
253
- } ;
254
- match decl {
255
- Decl :: Fn ( n) => {
256
- self . add_binding_for_ident ( & mut n. ident ) ;
257
- }
258
- Decl :: Class ( n) => {
259
- self . add_binding_for_ident ( & mut n. ident ) ;
260
- }
261
- _ => { }
262
- }
263
- }
264
-
265
- fn lookahead_hoist_stmts ( & mut self , stmts : & mut Vec < Stmt > ) {
266
- for stmt in stmts {
267
- self . lookahead_hoist_stmt ( stmt) ;
268
- }
269
- }
270
-
271
- fn lookahead_hoist_module_items ( & mut self , stmts : & mut Vec < ModuleItem > ) {
272
- debug_assert ! ( self . current_scope_id == ScopeId :: TOP_LEVEL ) ;
273
- for stmt in stmts {
274
- let decl = match stmt {
275
- ModuleItem :: ModuleDecl ( m) => m,
276
- ModuleItem :: Stmt ( stmt) => {
277
- self . lookahead_hoist_stmt ( stmt) ;
278
- continue ;
279
- }
280
- } ;
281
- match decl {
282
- ModuleDecl :: Import ( n) => {
283
- for spec in & mut n. specifiers {
284
- match spec {
285
- ImportSpecifier :: Named ( n) => {
286
- self . add_binding_for_ident ( & mut n. local ) ;
287
- }
288
- ImportSpecifier :: Default ( n) => {
289
- self . add_binding_for_ident ( & mut n. local ) ;
290
- }
291
- ImportSpecifier :: Namespace ( n) => {
292
- self . add_binding_for_ident ( & mut n. local ) ;
293
- }
294
- }
295
- }
296
- }
297
- ModuleDecl :: ExportDecl ( n) => match & mut n. decl {
298
- Decl :: Fn ( n) => {
299
- self . add_binding_for_ident ( & mut n. ident ) ;
300
- }
301
- Decl :: Class ( n) => {
302
- self . add_binding_for_ident ( & mut n. ident ) ;
303
- }
304
- _ => { }
305
- } ,
306
- _ => { }
307
- }
308
- }
309
- }
310
-
311
264
fn find_binding_or_add_into_global ( & mut self , ident : & mut Ident ) {
312
265
if let Some ( to) = self . lookup_binding ( & ident. sym , self . current_scope_id ) {
313
266
self . add_reference ( ident, to) ;
@@ -421,7 +374,9 @@ impl VisitMut for Resolver {
421
374
422
375
fn visit_mut_var_decl ( & mut self , node : & mut VarDecl ) {
423
376
for decl in & mut node. decls {
424
- self . visit_pat_with_binding ( & mut decl. name , node. kind == VarDeclKind :: Var ) ;
377
+ if node. kind != VarDeclKind :: Var {
378
+ self . visit_pat_with_binding ( & mut decl. name , false ) ;
379
+ }
425
380
decl. init . visit_mut_children_with ( self ) ;
426
381
}
427
382
}
@@ -436,10 +391,16 @@ impl VisitMut for Resolver {
436
391
self . visit_pat_with_binding ( & mut node. pat , false ) ;
437
392
}
438
393
394
+ fn visit_mut_function ( & mut self , node : & mut Function ) {
395
+ let mut lookahead = DeepLookahead { r : self } ;
396
+ node. body . visit_mut_with ( & mut lookahead) ;
397
+ node. visit_mut_children_with ( self ) ;
398
+ }
399
+
439
400
fn visit_mut_fn_decl ( & mut self , node : & mut FnDecl ) {
440
401
debug_assert ! ( self . is_ref_to_itself( node. ident. node_id) ) ;
441
402
self . with_new_scope ( ScopeKind :: Fn , |this| {
442
- node. function . visit_mut_children_with ( this) ;
403
+ node. function . visit_mut_with ( this) ;
443
404
} ) ;
444
405
}
445
406
@@ -449,7 +410,7 @@ impl VisitMut for Resolver {
449
410
this. add_binding_for_ident ( ident) ;
450
411
}
451
412
this. with_new_scope ( ScopeKind :: Fn , |this| {
452
- node. function . visit_mut_children_with ( this) ;
413
+ node. function . visit_mut_with ( this) ;
453
414
} ) ;
454
415
} ) ;
455
416
}
@@ -459,6 +420,10 @@ impl VisitMut for Resolver {
459
420
for param in & mut node. params {
460
421
this. visit_pat_with_binding ( param, false ) ;
461
422
}
423
+ if let Some ( block_stmt) = node. body . as_mut_block_stmt ( ) {
424
+ let mut lookahead = DeepLookahead { r : this } ;
425
+ block_stmt. visit_mut_children_with ( & mut lookahead) ;
426
+ }
462
427
node. body . visit_mut_children_with ( this) ;
463
428
} ) ;
464
429
}
@@ -480,12 +445,16 @@ impl VisitMut for Resolver {
480
445
}
481
446
482
447
fn visit_mut_stmts ( & mut self , node : & mut Vec < Stmt > ) {
483
- self . lookahead_hoist_stmts ( node) ;
448
+ let mut lookahead = ShadowLookahead { r : self } ;
449
+ lookahead. lookahead_hoist_stmts ( node) ;
484
450
node. visit_mut_children_with ( self ) ;
485
451
}
486
452
487
453
fn visit_mut_module_items ( & mut self , node : & mut Vec < ModuleItem > ) {
488
- self . lookahead_hoist_module_items ( node) ;
454
+ let mut lookahead = ShadowLookahead { r : self } ;
455
+ lookahead. lookahead_hoist_module_items ( node) ;
456
+ let mut lookahead = DeepLookahead { r : self } ;
457
+ node. visit_mut_children_with ( & mut lookahead) ;
489
458
node. visit_mut_children_with ( self ) ;
490
459
}
491
460
@@ -552,7 +521,119 @@ impl VisitMut for Resolver {
552
521
553
522
fn visit_mut_script ( & mut self , node : & mut Script ) {
554
523
self . start_visit_with ( |this| {
524
+ let mut lookahead = DeepLookahead { r : this } ;
525
+ node. body . visit_mut_children_with ( & mut lookahead) ;
555
526
this. visit_mut_stmts ( & mut node. body ) ;
556
527
} ) ;
557
528
}
558
529
}
530
+
531
+ /// only lookahead current block
532
+ struct ShadowLookahead < ' r > {
533
+ r : & ' r mut Resolver ,
534
+ }
535
+
536
+ impl < ' r > ShadowLookahead < ' r > {
537
+ fn lookahead_hoist_stmt ( & mut self , stmt : & mut Stmt ) {
538
+ let Stmt :: Decl ( decl) = stmt else {
539
+ return ;
540
+ } ;
541
+ match decl {
542
+ Decl :: Fn ( n) => {
543
+ self . r . add_binding_for_ident ( & mut n. ident ) ;
544
+ }
545
+ Decl :: Class ( n) => {
546
+ self . r . add_binding_for_ident ( & mut n. ident ) ;
547
+ }
548
+ _ => { }
549
+ }
550
+ }
551
+
552
+ fn lookahead_hoist_stmts ( & mut self , stmts : & mut Vec < Stmt > ) {
553
+ for stmt in stmts {
554
+ self . lookahead_hoist_stmt ( stmt) ;
555
+ }
556
+ }
557
+
558
+ fn lookahead_hoist_module_items ( & mut self , stmts : & mut Vec < ModuleItem > ) {
559
+ debug_assert ! ( self . r. current_scope_id == ScopeId :: TOP_LEVEL ) ;
560
+ for stmt in stmts {
561
+ let decl = match stmt {
562
+ ModuleItem :: ModuleDecl ( m) => m,
563
+ ModuleItem :: Stmt ( stmt) => {
564
+ self . lookahead_hoist_stmt ( stmt) ;
565
+ continue ;
566
+ }
567
+ } ;
568
+ match decl {
569
+ ModuleDecl :: Import ( n) => {
570
+ for spec in & mut n. specifiers {
571
+ match spec {
572
+ ImportSpecifier :: Named ( n) => {
573
+ self . r . add_binding_for_ident ( & mut n. local ) ;
574
+ }
575
+ ImportSpecifier :: Default ( n) => {
576
+ self . r . add_binding_for_ident ( & mut n. local ) ;
577
+ }
578
+ ImportSpecifier :: Namespace ( n) => {
579
+ self . r . add_binding_for_ident ( & mut n. local ) ;
580
+ }
581
+ }
582
+ }
583
+ }
584
+ ModuleDecl :: ExportDecl ( n) => match & mut n. decl {
585
+ Decl :: Fn ( n) => {
586
+ self . r . add_binding_for_ident ( & mut n. ident ) ;
587
+ }
588
+ Decl :: Class ( n) => {
589
+ self . r . add_binding_for_ident ( & mut n. ident ) ;
590
+ }
591
+ _ => { }
592
+ } ,
593
+ _ => { }
594
+ }
595
+ }
596
+ }
597
+ }
598
+
599
+ /// lookahead current block and its child blocks(exclude function, class...)
600
+ struct DeepLookahead < ' r > {
601
+ r : & ' r mut Resolver ,
602
+ }
603
+
604
+ impl < ' r > VisitMut for DeepLookahead < ' r > {
605
+ noop_visit_mut_type ! ( ) ;
606
+
607
+ fn visit_mut_arrow_expr ( & mut self , _: & mut ArrowExpr ) { }
608
+
609
+ fn visit_mut_constructor ( & mut self , _: & mut Constructor ) { }
610
+
611
+ fn visit_mut_expr ( & mut self , _: & mut Expr ) { }
612
+
613
+ fn visit_mut_function ( & mut self , _: & mut Function ) { }
614
+
615
+ fn visit_mut_param ( & mut self , _: & mut Param ) { }
616
+
617
+ fn visit_mut_assign_target ( & mut self , _: & mut AssignTarget ) { }
618
+
619
+ fn visit_mut_setter_prop ( & mut self , _: & mut SetterProp ) { }
620
+
621
+ fn visit_mut_tagged_tpl ( & mut self , _: & mut TaggedTpl ) { }
622
+
623
+ fn visit_mut_tpl ( & mut self , _: & mut Tpl ) { }
624
+
625
+ fn visit_mut_fn_decl ( & mut self , _: & mut FnDecl ) { }
626
+
627
+ fn visit_mut_class_decl ( & mut self , _: & mut ClassDecl ) { }
628
+
629
+ fn visit_mut_import_decl ( & mut self , _: & mut ImportDecl ) { }
630
+
631
+ fn visit_mut_var_decl ( & mut self , node : & mut VarDecl ) {
632
+ if node. kind != VarDeclKind :: Var {
633
+ return ;
634
+ }
635
+ for decl in & mut node. decls {
636
+ self . r . visit_pat_with_binding ( & mut decl. name , true ) ;
637
+ }
638
+ }
639
+ }
0 commit comments