@@ -322,8 +322,187 @@ fn is_terminal_stmt(stmt: &Stmt) -> bool {
322
322
impl VisitMut for DeadCodeEliminator {
323
323
noop_visit_mut_type ! ( ) ;
324
324
325
+ fn visit_mut_block_stmt ( & mut self , block : & mut BlockStmt ) {
326
+ // Create a new scope for the block
327
+ let old_scope = self . enter_scope ( Some ( self . current_scope ) ) ;
328
+
329
+ // Visit all statements in the block
330
+ self . visit_mut_stmts ( & mut block. stmts ) ;
331
+
332
+ // Exit block scope
333
+ self . exit_scope ( old_scope) ;
334
+ }
335
+
325
336
// Implementation for all the necessary visit_mut_* methods
326
337
338
+ fn visit_mut_class ( & mut self , class : & mut Class ) {
339
+ // 클래스 내부 요소 방문 전에 상태 저장
340
+ let old_pure = self . in_pure_context ;
341
+ self . in_pure_context = false ;
342
+
343
+ // 상속(extends) 처리
344
+ if let Some ( parent) = & mut class. super_class {
345
+ // 부모 클래스도 방문해서 참조 마킹
346
+ if let Expr :: Ident ( ident) = & * * parent {
347
+ let id = ( ident. sym . clone ( ) , ident. ctxt ) ;
348
+ self . register_reference ( & id) ;
349
+ }
350
+ parent. visit_mut_with ( self ) ;
351
+ }
352
+
353
+ // 클래스 내부 요소 처리
354
+ for member in & mut class. body {
355
+ match member {
356
+ ClassMember :: Constructor ( constructor) => {
357
+ // 생성자 파라미터 처리 - params는 Option이 아닌 Vec 타입
358
+ for param in & constructor. params {
359
+ if let ParamOrTsParamProp :: Param ( param) = param {
360
+ let ids = find_pat_ids ( & param. pat ) ;
361
+ for id in ids {
362
+ self . register_declaration ( id, false , false ) ;
363
+ }
364
+ }
365
+ }
366
+
367
+ // 생성자 본문 방문
368
+ if let Some ( body) = & mut constructor. body {
369
+ body. visit_mut_with ( self ) ;
370
+ }
371
+ }
372
+ ClassMember :: Method ( method) => {
373
+ // 메서드 방문 - function은 Option이 아닌 Box<Function> 타입
374
+ method. function . visit_mut_with ( self ) ;
375
+ }
376
+ ClassMember :: PrivateMethod ( priv_method) => {
377
+ // 프라이빗 메서드 방문 - function은 Option이 아닌 Box<Function> 타입
378
+ priv_method. function . visit_mut_with ( self ) ;
379
+ }
380
+ ClassMember :: ClassProp ( prop) => {
381
+ // 프로퍼티 초기화 값 방문
382
+ if let Some ( value) = & mut prop. value {
383
+ value. visit_mut_with ( self ) ;
384
+ }
385
+ }
386
+ ClassMember :: PrivateProp ( priv_prop) => {
387
+ // 프라이빗 프로퍼티 초기화 값 방문
388
+ if let Some ( value) = & mut priv_prop. value {
389
+ value. visit_mut_with ( self ) ;
390
+ }
391
+ }
392
+ _ => {
393
+ // Process other class members
394
+ member. visit_mut_children_with ( self ) ;
395
+ }
396
+ }
397
+ }
398
+
399
+ // Restore original state
400
+ self . in_pure_context = old_pure;
401
+ }
402
+
403
+ fn visit_mut_class_decl ( & mut self , class_decl : & mut ClassDecl ) {
404
+ // Process class name
405
+ let id = ( class_decl. ident . sym . clone ( ) , class_decl. ident . ctxt ) ;
406
+ self . register_declaration ( id, false , false ) ;
407
+
408
+ // Visit class contents
409
+ class_decl. class . visit_mut_with ( self ) ;
410
+ }
411
+
412
+ fn visit_mut_expr ( & mut self , expr : & mut Expr ) {
413
+ match expr {
414
+ Expr :: Ident ( ident) => {
415
+ let id = ( ident. sym . clone ( ) , ident. ctxt ) ;
416
+ self . register_reference ( & id) ;
417
+
418
+ // Mark import specifier as used if this identifier is an import
419
+ if let Some ( used) = self . import_specifiers . get_mut ( & id) {
420
+ * used = true ;
421
+ }
422
+ }
423
+ // Also handle member expressions to catch namespace imports usage
424
+ Expr :: Member ( member) => {
425
+ // If we're accessing a property of a namespace import, mark it as used
426
+ if let Expr :: Ident ( obj) = & * member. obj {
427
+ let id = ( obj. sym . clone ( ) , obj. ctxt ) ;
428
+ self . register_reference ( & id) ;
429
+
430
+ // Mark namespace import as used
431
+ if let Some ( used) = self . import_specifiers . get_mut ( & id) {
432
+ * used = true ;
433
+ }
434
+ }
435
+
436
+ // Continue normal visitation
437
+ member. visit_mut_children_with ( self ) ;
438
+ }
439
+ Expr :: Assign ( assign) => {
440
+ // Visit right side first
441
+ self . visit_mut_expr ( & mut assign. right ) ;
442
+
443
+ // 왼쪽 변이를 직접 처리하는 것은 복잡하므로 이 구현에서는 이 부분을
444
+ // 단순화합니다. 대신 right의 참조를 처리한 다음, 방문 시스템이
445
+ // 나머지를 처리하게 합니다.
446
+
447
+ // 자식 노드 방문
448
+ assign. visit_mut_children_with ( self ) ;
449
+ }
450
+ Expr :: Update ( update) => {
451
+ if let Expr :: Ident ( ident) = & * update. arg {
452
+ let id = ( ident. sym . clone ( ) , ident. ctxt ) ;
453
+ self . register_mutation ( & id) ;
454
+ } else {
455
+ update. arg . visit_mut_with ( self ) ;
456
+ }
457
+ }
458
+ // Save and restore pure context state
459
+ Expr :: Arrow ( arrow) => {
460
+ let old_pure = self . in_pure_context ;
461
+ self . in_pure_context = false ;
462
+
463
+ let old_scope = self . enter_scope ( Some ( self . current_scope ) ) ;
464
+
465
+ // Process parameters
466
+ for pat in & arrow. params {
467
+ self . process_pat ( pat, false ) ;
468
+ }
469
+
470
+ arrow. body . visit_mut_with ( self ) ;
471
+
472
+ self . exit_scope ( old_scope) ;
473
+ self . in_pure_context = old_pure;
474
+ }
475
+ // For all other expressions, just visit children normally
476
+ _ => {
477
+ expr. visit_mut_children_with ( self ) ;
478
+ }
479
+ }
480
+ }
481
+
482
+ fn visit_mut_function ( & mut self , f : & mut Function ) {
483
+ // Create a new scope for the function
484
+ let old_scope = self . enter_scope ( Some ( self . current_scope ) ) ;
485
+
486
+ // Process parameters
487
+ for param in & f. params {
488
+ let ids = find_pat_ids ( & param. pat ) ;
489
+ for id in ids {
490
+ self . register_declaration ( id, false , false ) ;
491
+ }
492
+ }
493
+
494
+ // Visit function body
495
+ f. body . visit_mut_with ( self ) ;
496
+
497
+ // Remove unreachable code in function body
498
+ if let Some ( body) = & mut f. body {
499
+ self . remove_unreachable_stmts ( & mut body. stmts ) ;
500
+ }
501
+
502
+ // Exit function scope
503
+ self . exit_scope ( old_scope) ;
504
+ }
505
+
327
506
fn visit_mut_module ( & mut self , module : & mut Module ) {
328
507
// Initialize the top-level module scope
329
508
let old_scope = self . enter_scope ( None ) ;
@@ -519,30 +698,6 @@ impl VisitMut for DeadCodeEliminator {
519
698
self . exit_scope ( old_scope) ;
520
699
}
521
700
522
- fn visit_mut_function ( & mut self , f : & mut Function ) {
523
- // Create a new scope for the function
524
- let old_scope = self . enter_scope ( Some ( self . current_scope ) ) ;
525
-
526
- // Process parameters
527
- for param in & f. params {
528
- let ids = find_pat_ids ( & param. pat ) ;
529
- for id in ids {
530
- self . register_declaration ( id, false , false ) ;
531
- }
532
- }
533
-
534
- // Visit function body
535
- f. body . visit_mut_with ( self ) ;
536
-
537
- // Remove unreachable code in function body
538
- if let Some ( body) = & mut f. body {
539
- self . remove_unreachable_stmts ( & mut body. stmts ) ;
540
- }
541
-
542
- // Exit function scope
543
- self . exit_scope ( old_scope) ;
544
- }
545
-
546
701
fn visit_mut_stmts ( & mut self , stmts : & mut Vec < Stmt > ) {
547
702
// First pass: visit all statements to collect references
548
703
for stmt in stmts. iter_mut ( ) {
@@ -561,17 +716,6 @@ impl VisitMut for DeadCodeEliminator {
561
716
}
562
717
}
563
718
564
- fn visit_mut_block_stmt ( & mut self , block : & mut BlockStmt ) {
565
- // Create a new scope for the block
566
- let old_scope = self . enter_scope ( Some ( self . current_scope ) ) ;
567
-
568
- // Visit all statements in the block
569
- self . visit_mut_stmts ( & mut block. stmts ) ;
570
-
571
- // Exit block scope
572
- self . exit_scope ( old_scope) ;
573
- }
574
-
575
719
fn visit_mut_var_declarator ( & mut self , decl : & mut VarDeclarator ) {
576
720
// Process variable name (destructuring pattern)
577
721
let ids: Vec < Id > = find_pat_ids ( & decl. name ) ;
@@ -584,150 +728,6 @@ impl VisitMut for DeadCodeEliminator {
584
728
self . visit_mut_expr ( init) ;
585
729
}
586
730
}
587
-
588
- fn visit_mut_expr ( & mut self , expr : & mut Expr ) {
589
- match expr {
590
- Expr :: Ident ( ident) => {
591
- let id = ( ident. sym . clone ( ) , ident. ctxt ) ;
592
- self . register_reference ( & id) ;
593
-
594
- // Mark import specifier as used if this identifier is an import
595
- if let Some ( used) = self . import_specifiers . get_mut ( & id) {
596
- * used = true ;
597
- }
598
- }
599
- // Also handle member expressions to catch namespace imports usage
600
- Expr :: Member ( member) => {
601
- // If we're accessing a property of a namespace import, mark it as used
602
- if let Expr :: Ident ( obj) = & * member. obj {
603
- let id = ( obj. sym . clone ( ) , obj. ctxt ) ;
604
- self . register_reference ( & id) ;
605
-
606
- // Mark namespace import as used
607
- if let Some ( used) = self . import_specifiers . get_mut ( & id) {
608
- * used = true ;
609
- }
610
- }
611
-
612
- // Continue normal visitation
613
- member. visit_mut_children_with ( self ) ;
614
- }
615
- Expr :: Assign ( assign) => {
616
- // Visit right side first
617
- self . visit_mut_expr ( & mut assign. right ) ;
618
-
619
- // 왼쪽 변이를 직접 처리하는 것은 복잡하므로 이 구현에서는 이 부분을
620
- // 단순화합니다. 대신 right의 참조를 처리한 다음, 방문 시스템이
621
- // 나머지를 처리하게 합니다.
622
-
623
- // 자식 노드 방문
624
- assign. visit_mut_children_with ( self ) ;
625
- }
626
- Expr :: Update ( update) => {
627
- if let Expr :: Ident ( ident) = & * update. arg {
628
- let id = ( ident. sym . clone ( ) , ident. ctxt ) ;
629
- self . register_mutation ( & id) ;
630
- } else {
631
- update. arg . visit_mut_with ( self ) ;
632
- }
633
- }
634
- // Save and restore pure context state
635
- Expr :: Arrow ( arrow) => {
636
- let old_pure = self . in_pure_context ;
637
- self . in_pure_context = false ;
638
-
639
- let old_scope = self . enter_scope ( Some ( self . current_scope ) ) ;
640
-
641
- // Process parameters
642
- for pat in & arrow. params {
643
- self . process_pat ( pat, false ) ;
644
- }
645
-
646
- arrow. body . visit_mut_with ( self ) ;
647
-
648
- self . exit_scope ( old_scope) ;
649
- self . in_pure_context = old_pure;
650
- }
651
- // For all other expressions, just visit children normally
652
- _ => {
653
- expr. visit_mut_children_with ( self ) ;
654
- }
655
- }
656
- }
657
-
658
- fn visit_mut_class ( & mut self , class : & mut Class ) {
659
- // 클래스 내부 요소 방문 전에 상태 저장
660
- let old_pure = self . in_pure_context ;
661
- self . in_pure_context = false ;
662
-
663
- // 상속(extends) 처리
664
- if let Some ( parent) = & mut class. super_class {
665
- // 부모 클래스도 방문해서 참조 마킹
666
- if let Expr :: Ident ( ident) = & * * parent {
667
- let id = ( ident. sym . clone ( ) , ident. ctxt ) ;
668
- self . register_reference ( & id) ;
669
- }
670
- parent. visit_mut_with ( self ) ;
671
- }
672
-
673
- // 클래스 내부 요소 처리
674
- for member in & mut class. body {
675
- match member {
676
- ClassMember :: Constructor ( constructor) => {
677
- // 생성자 파라미터 처리 - params는 Option이 아닌 Vec 타입
678
- for param in & constructor. params {
679
- if let ParamOrTsParamProp :: Param ( param) = param {
680
- let ids = find_pat_ids ( & param. pat ) ;
681
- for id in ids {
682
- self . register_declaration ( id, false , false ) ;
683
- }
684
- }
685
- }
686
-
687
- // 생성자 본문 방문
688
- if let Some ( body) = & mut constructor. body {
689
- body. visit_mut_with ( self ) ;
690
- }
691
- }
692
- ClassMember :: Method ( method) => {
693
- // 메서드 방문 - function은 Option이 아닌 Box<Function> 타입
694
- method. function . visit_mut_with ( self ) ;
695
- }
696
- ClassMember :: PrivateMethod ( priv_method) => {
697
- // 프라이빗 메서드 방문 - function은 Option이 아닌 Box<Function> 타입
698
- priv_method. function . visit_mut_with ( self ) ;
699
- }
700
- ClassMember :: ClassProp ( prop) => {
701
- // 프로퍼티 초기화 값 방문
702
- if let Some ( value) = & mut prop. value {
703
- value. visit_mut_with ( self ) ;
704
- }
705
- }
706
- ClassMember :: PrivateProp ( priv_prop) => {
707
- // 프라이빗 프로퍼티 초기화 값 방문
708
- if let Some ( value) = & mut priv_prop. value {
709
- value. visit_mut_with ( self ) ;
710
- }
711
- }
712
- _ => {
713
- // Process other class members
714
- member. visit_mut_children_with ( self ) ;
715
- }
716
- }
717
- }
718
-
719
- // Restore original state
720
- self . in_pure_context = old_pure;
721
- }
722
-
723
- fn visit_mut_class_decl ( & mut self , class_decl : & mut ClassDecl ) {
724
- // Process class name
725
- let id = ( class_decl. ident . sym . clone ( ) , class_decl. ident . ctxt ) ;
726
- self . register_declaration ( id, false , false ) ;
727
-
728
- // Visit class contents
729
- class_decl. class . visit_mut_with ( self ) ;
730
- }
731
731
}
732
732
733
733
impl Repeated for DeadCodeEliminator {
0 commit comments