@@ -217,6 +217,20 @@ impl Resolver {
217217 for prop in n. props . iter_mut ( ) {
218218 match prop {
219219 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+ } ;
220234 self . visit_pat_with_binding ( & mut p. value , is_var) ;
221235 }
222236 ObjectPatProp :: Assign ( p) => {
@@ -247,67 +261,6 @@ impl Resolver {
247261 }
248262 }
249263
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-
311264 fn find_binding_or_add_into_global ( & mut self , ident : & mut Ident ) {
312265 if let Some ( to) = self . lookup_binding ( & ident. sym , self . current_scope_id ) {
313266 self . add_reference ( ident, to) ;
@@ -421,7 +374,9 @@ impl VisitMut for Resolver {
421374
422375 fn visit_mut_var_decl ( & mut self , node : & mut VarDecl ) {
423376 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+ }
425380 decl. init . visit_mut_children_with ( self ) ;
426381 }
427382 }
@@ -436,10 +391,16 @@ impl VisitMut for Resolver {
436391 self . visit_pat_with_binding ( & mut node. pat , false ) ;
437392 }
438393
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+
439400 fn visit_mut_fn_decl ( & mut self , node : & mut FnDecl ) {
440401 debug_assert ! ( self . is_ref_to_itself( node. ident. node_id) ) ;
441402 self . with_new_scope ( ScopeKind :: Fn , |this| {
442- node. function . visit_mut_children_with ( this) ;
403+ node. function . visit_mut_with ( this) ;
443404 } ) ;
444405 }
445406
@@ -449,7 +410,7 @@ impl VisitMut for Resolver {
449410 this. add_binding_for_ident ( ident) ;
450411 }
451412 this. with_new_scope ( ScopeKind :: Fn , |this| {
452- node. function . visit_mut_children_with ( this) ;
413+ node. function . visit_mut_with ( this) ;
453414 } ) ;
454415 } ) ;
455416 }
@@ -459,6 +420,10 @@ impl VisitMut for Resolver {
459420 for param in & mut node. params {
460421 this. visit_pat_with_binding ( param, false ) ;
461422 }
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+ }
462427 node. body . visit_mut_children_with ( this) ;
463428 } ) ;
464429 }
@@ -480,12 +445,16 @@ impl VisitMut for Resolver {
480445 }
481446
482447 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) ;
484450 node. visit_mut_children_with ( self ) ;
485451 }
486452
487453 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) ;
489458 node. visit_mut_children_with ( self ) ;
490459 }
491460
@@ -552,7 +521,119 @@ impl VisitMut for Resolver {
552521
553522 fn visit_mut_script ( & mut self , node : & mut Script ) {
554523 self . start_visit_with ( |this| {
524+ let mut lookahead = DeepLookahead { r : this } ;
525+ node. body . visit_mut_children_with ( & mut lookahead) ;
555526 this. visit_mut_stmts ( & mut node. body ) ;
556527 } ) ;
557528 }
558529}
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