@@ -49,7 +49,8 @@ use oxc_ast::{
4949 } ,
5050 NONE ,
5151} ;
52- use oxc_span:: SPAN ;
52+ use oxc_semantic:: ScopeFlags ;
53+ use oxc_span:: { GetSpan , SPAN } ;
5354use oxc_traverse:: { Ancestor , Traverse , TraverseCtx } ;
5455
5556use crate :: { common:: helper_loader:: Helper , context:: TransformCtx } ;
@@ -102,6 +103,11 @@ impl<'a, 'ctx> Traverse<'a> for AsyncToGenerator<'a, 'ctx> {
102103 }
103104 let new_function = self . transform_function ( func, ctx) ;
104105 * expr = ctx. ast . expression_from_function ( new_function) ;
106+ } else if let Expression :: ArrowFunctionExpression ( arrow) = expr {
107+ if !arrow. r#async {
108+ return ;
109+ }
110+ * expr = self . transform_arrow_function ( arrow, ctx) ;
105111 }
106112 }
107113
@@ -134,50 +140,6 @@ impl<'a, 'ctx> Traverse<'a> for AsyncToGenerator<'a, 'ctx> {
134140 }
135141 }
136142 }
137-
138- fn exit_arrow_function_expression (
139- & mut self ,
140- arrow : & mut ArrowFunctionExpression < ' a > ,
141- ctx : & mut TraverseCtx < ' a > ,
142- ) {
143- if !arrow. r#async {
144- return ;
145- }
146- let body = ctx. ast . function_body (
147- SPAN ,
148- ctx. ast . move_vec ( & mut arrow. body . directives ) ,
149- ctx. ast . move_vec ( & mut arrow. body . statements ) ,
150- ) ;
151- let target = ctx. ast . function (
152- FunctionType :: FunctionExpression ,
153- SPAN ,
154- None ,
155- true ,
156- false ,
157- false ,
158- arrow. type_parameters . take ( ) ,
159- NONE ,
160- ctx. ast . alloc ( ctx. ast . formal_parameters (
161- SPAN ,
162- arrow. params . kind ,
163- ctx. ast . move_vec ( & mut arrow. params . items ) ,
164- arrow. params . rest . take ( ) ,
165- ) ) ,
166- arrow. return_type . take ( ) ,
167- Some ( body) ,
168- ) ;
169- let parameters =
170- ctx. ast . vec1 ( ctx. ast . argument_expression ( ctx. ast . expression_from_function ( target) ) ) ;
171- let call = self . ctx . helper_call_expr ( Helper :: AsyncToGenerator , parameters, ctx) ;
172- let body = ctx. ast . function_body (
173- SPAN ,
174- ctx. ast . vec ( ) ,
175- ctx. ast . vec1 ( ctx. ast . statement_expression ( SPAN , call) ) ,
176- ) ;
177- arrow. body = ctx. ast . alloc ( body) ;
178- arrow. r#async = false ;
179- arrow. expression = true ;
180- }
181143}
182144
183145impl < ' a , ' ctx > AsyncToGenerator < ' a , ' ctx > {
@@ -226,4 +188,46 @@ impl<'a, 'ctx> AsyncToGenerator<'a, 'ctx> {
226188 Some ( body) ,
227189 )
228190 }
191+
192+ fn transform_arrow_function (
193+ & self ,
194+ arrow : & mut ArrowFunctionExpression < ' a > ,
195+ ctx : & mut TraverseCtx < ' a > ,
196+ ) -> Expression < ' a > {
197+ let mut body = ctx. ast . function_body (
198+ SPAN ,
199+ ctx. ast . move_vec ( & mut arrow. body . directives ) ,
200+ ctx. ast . move_vec ( & mut arrow. body . statements ) ,
201+ ) ;
202+
203+ // If the arrow's expression is true, we need to wrap the only one expression with return statement.
204+ if arrow. expression {
205+ let statement = body. statements . first_mut ( ) . unwrap ( ) ;
206+ let expression = match statement {
207+ Statement :: ExpressionStatement ( es) => ctx. ast . move_expression ( & mut es. expression ) ,
208+ _ => unreachable ! ( ) ,
209+ } ;
210+ * statement = ctx. ast . statement_return ( expression. span ( ) , Some ( expression) ) ;
211+ }
212+
213+ let r#type = FunctionType :: FunctionExpression ;
214+ let parameters = ctx. ast . alloc ( ctx. ast . formal_parameters (
215+ SPAN ,
216+ arrow. params . kind ,
217+ ctx. ast . move_vec ( & mut arrow. params . items ) ,
218+ arrow. params . rest . take ( ) ,
219+ ) ) ;
220+ let body = Some ( body) ;
221+ let mut function = ctx
222+ . ast
223+ . function ( r#type, SPAN , None , true , false , false , NONE , NONE , parameters, NONE , body) ;
224+ function. scope_id = arrow. scope_id . clone ( ) ;
225+ if let Some ( scope_id) = function. scope_id . get ( ) {
226+ ctx. scopes_mut ( ) . get_flags_mut ( scope_id) . remove ( ScopeFlags :: Arrow ) ;
227+ }
228+
229+ let arguments =
230+ ctx. ast . vec1 ( ctx. ast . argument_expression ( ctx. ast . expression_from_function ( function) ) ) ;
231+ self . ctx . helper_call_expr ( Helper :: AsyncToGenerator , arguments, ctx)
232+ }
229233}
0 commit comments