@@ -2,7 +2,7 @@ use crate::{
22 perf:: Check ,
33 util:: { prepend, undefined, ExprFactory , StmtLike } ,
44} ;
5- use std:: { fmt :: Debug , iter:: once, mem} ;
5+ use std:: { iter:: once, mem} ;
66use swc_common:: { Spanned , DUMMY_SP } ;
77use swc_ecma_ast:: * ;
88use swc_ecma_transforms_macros:: fast_path;
@@ -13,9 +13,10 @@ pub fn optional_chaining() -> impl Fold {
1313 OptChaining :: default ( )
1414}
1515
16- #[ derive( Debug , Default ) ]
16+ #[ derive( Default ) ]
1717struct OptChaining {
18- vars : Vec < VarDeclarator > ,
18+ vars_without_init : Vec < VarDeclarator > ,
19+ vars_with_init : Vec < VarDeclarator > ,
1920}
2021
2122#[ fast_path( ShouldWork ) ]
@@ -56,24 +57,39 @@ impl OptChaining {
5657 Vec < T > : FoldWith < Self > ,
5758 {
5859 // This is to support nested block statements
59- let old = mem:: replace ( & mut self . vars , vec ! [ ] ) ;
60+ let old_no_init = mem:: replace ( & mut self . vars_without_init , vec ! [ ] ) ;
61+ let old_init = mem:: replace ( & mut self . vars_with_init , vec ! [ ] ) ;
62+
63+ let mut new: Vec < T > = vec ! [ ] ;
6064
61- let mut stmts = stmts. fold_children_with ( self ) ;
65+ for stmt in stmts {
66+ let stmt = stmt. fold_with ( self ) ;
67+ if !self . vars_with_init . is_empty ( ) {
68+ new. push ( T :: from_stmt ( Stmt :: Decl ( Decl :: Var ( VarDecl {
69+ span : DUMMY_SP ,
70+ declare : false ,
71+ kind : VarDeclKind :: Var ,
72+ decls : mem:: replace ( & mut self . vars_with_init , vec ! [ ] ) ,
73+ } ) ) ) ) ;
74+ }
75+ new. push ( stmt) ;
76+ }
6277
63- if !self . vars . is_empty ( ) {
78+ if !self . vars_without_init . is_empty ( ) {
6479 prepend (
65- & mut stmts ,
80+ & mut new ,
6681 T :: from_stmt ( Stmt :: Decl ( Decl :: Var ( VarDecl {
6782 span : DUMMY_SP ,
6883 declare : false ,
6984 kind : VarDeclKind :: Var ,
70- decls : mem:: replace ( & mut self . vars , vec ! [ ] ) ,
85+ decls : mem:: replace ( & mut self . vars_without_init , vec ! [ ] ) ,
7186 } ) ) ) ,
7287 ) ;
7388 }
7489
75- self . vars = old;
76- stmts
90+ self . vars_without_init = old_no_init;
91+ self . vars_with_init = old_init;
92+ new
7793 }
7894}
7995
@@ -335,7 +351,7 @@ impl OptChaining {
335351 Expr :: Ident ( ..) => ( Box :: new ( obj. clone ( ) ) , Box :: new ( obj) , e. expr ) ,
336352 _ => {
337353 let i = private_ident ! ( obj_span, "ref" ) ;
338- self . vars . push ( VarDeclarator {
354+ self . vars_without_init . push ( VarDeclarator {
339355 span : obj_span,
340356 definite : false ,
341357 name : Pat :: Ident ( i. clone ( ) ) ,
@@ -420,7 +436,7 @@ impl OptChaining {
420436 "_obj" ,
421437 ) ;
422438 let obj = if !is_super_access && aliased {
423- self . vars . push ( VarDeclarator {
439+ self . vars_with_init . push ( VarDeclarator {
424440 span : obj_span,
425441 definite : false ,
426442 name : Pat :: Ident ( this_obj. clone ( ) ) ,
@@ -432,7 +448,7 @@ impl OptChaining {
432448 obj
433449 } ;
434450 let i = private_ident ! ( obj_span, "ref" ) ;
435- self . vars . push ( VarDeclarator {
451+ self . vars_without_init . push ( VarDeclarator {
436452 span : obj_span,
437453 definite : false ,
438454 name : Pat :: Ident ( i. clone ( ) ) ,
0 commit comments