@@ -39,6 +39,7 @@ use rustc_hash::FxHashMap;
3939
4040use oxc_allocator:: { Address , Box as ArenaBox , GetAddress , Vec as ArenaVec } ;
4141use oxc_ast:: { NONE , ast:: * } ;
42+ use oxc_data_structures:: stack:: NonEmptyStack ;
4243use oxc_ecmascript:: BoundNames ;
4344use oxc_semantic:: { ScopeFlags , ScopeId , SymbolFlags } ;
4445use oxc_span:: { Atom , SPAN } ;
@@ -50,11 +51,19 @@ pub struct ExplicitResourceManagement<'a, 'ctx> {
5051 ctx : & ' ctx TransformCtx < ' a > ,
5152
5253 top_level_using : FxHashMap < Address , /* is await-using */ bool > ,
54+
55+ /// keeps track of wether the current static block contains a `using` declaration
56+ /// so that we can transform it in `exit_static_block`
57+ static_blocks_stack : NonEmptyStack < bool > ,
5358}
5459
5560impl < ' a , ' ctx > ExplicitResourceManagement < ' a , ' ctx > {
5661 pub fn new ( ctx : & ' ctx TransformCtx < ' a > ) -> Self {
57- Self { ctx, top_level_using : FxHashMap :: default ( ) }
62+ Self {
63+ ctx,
64+ top_level_using : FxHashMap :: default ( ) ,
65+ static_blocks_stack : NonEmptyStack :: new ( false ) ,
66+ }
5867 }
5968}
6069
@@ -123,6 +132,10 @@ impl<'a> Traverse<'a> for ExplicitResourceManagement<'a, '_> {
123132 } ;
124133 }
125134
135+ fn enter_static_block ( & mut self , _node : & mut StaticBlock < ' a > , _ctx : & mut TraverseCtx < ' a > ) {
136+ self . static_blocks_stack . push ( false ) ;
137+ }
138+
126139 /// Transform class static block.
127140 ///
128141 /// ```js
@@ -144,11 +157,25 @@ impl<'a> Traverse<'a> for ExplicitResourceManagement<'a, '_> {
144157 /// }
145158 /// ```
146159 fn exit_static_block ( & mut self , block : & mut StaticBlock < ' a > , ctx : & mut TraverseCtx < ' a > ) {
147- let scope_id = block. scope_id ( ) ;
148- if let Some ( replacement) =
149- self . transform_statements ( & mut block. body , None , scope_id, scope_id, ctx)
160+ if self . static_blocks_stack . pop ( ) {
161+ let scope_id = block. scope_id ( ) ;
162+ if let Some ( replacement) =
163+ self . transform_statements ( & mut block. body , None , scope_id, scope_id, ctx)
164+ {
165+ block. body = ctx. ast . vec1 ( replacement) ;
166+ }
167+ }
168+ }
169+
170+ fn enter_variable_declaration (
171+ & mut self ,
172+ node : & mut VariableDeclaration < ' a > ,
173+ ctx : & mut TraverseCtx < ' a > ,
174+ ) {
175+ if matches ! ( node. kind, VariableDeclarationKind :: Using | VariableDeclarationKind :: AwaitUsing )
176+ && ctx. parent ( ) . is_static_block ( )
150177 {
151- block . body = ctx . ast . vec1 ( replacement ) ;
178+ * self . static_blocks_stack . last_mut ( ) = true ;
152179 }
153180 }
154181
0 commit comments