@@ -51,6 +51,7 @@ use std::mem;
51
51
52
52
use oxc_allocator:: CloneIn ;
53
53
use oxc_ast:: { ast:: * , NONE } ;
54
+ use oxc_semantic:: ScopeFlags ;
54
55
use oxc_span:: SPAN ;
55
56
use oxc_traverse:: { Ancestor , BoundIdentifier , MaybeBoundIdentifier , Traverse , TraverseCtx } ;
56
57
@@ -244,14 +245,19 @@ impl<'a> OptionalChaining<'a, '_> {
244
245
245
246
/// Wrap the expression with an arrow function
246
247
///
247
- /// `expr` -> `() => { return expr; }`
248
- fn wrap_arrow_function ( expr : & mut Expression < ' a > , ctx : & mut TraverseCtx < ' a > ) -> Expression < ' a > {
248
+ /// `expr` -> `(() => { return expr; })()`
249
+ fn wrap_arrow_function_iife (
250
+ expr : & mut Expression < ' a > ,
251
+ ctx : & mut TraverseCtx < ' a > ,
252
+ ) -> Expression < ' a > {
253
+ let scope_id =
254
+ ctx. insert_scope_below_expression ( expr, ScopeFlags :: Arrow | ScopeFlags :: Function ) ;
255
+
249
256
let kind = FormalParameterKind :: ArrowFormalParameters ;
250
257
let params = ctx. ast . formal_parameters ( SPAN , kind, ctx. ast . vec ( ) , NONE ) ;
251
258
let statements =
252
259
ctx. ast . vec1 ( ctx. ast . statement_return ( SPAN , Some ( ctx. ast . move_expression ( expr) ) ) ) ;
253
260
let body = ctx. ast . function_body ( SPAN , ctx. ast . vec ( ) , statements) ;
254
- let scope_id = ctx. current_scope_id ( ) ;
255
261
let arrow = ctx. ast . alloc_arrow_function_expression_with_scope_id (
256
262
SPAN , false , false , NONE , params, NONE , body, scope_id,
257
263
) ;
@@ -306,7 +312,7 @@ impl<'a> OptionalChaining<'a, '_> {
306
312
// To insert the temp binding in the correct scope, we wrap the expression with
307
313
// an arrow function. During the chain expression transformation, the temp binding
308
314
// will be inserted into the arrow function's body.
309
- Self :: wrap_arrow_function ( expr, ctx)
315
+ Self :: wrap_arrow_function_iife ( expr, ctx)
310
316
} else {
311
317
self . transform_chain_expression_impl ( false , expr, ctx)
312
318
}
@@ -320,7 +326,7 @@ impl<'a> OptionalChaining<'a, '_> {
320
326
) {
321
327
* expr = if self . is_inside_function_parameter {
322
328
// Same as the above `transform_chain_expression` explanation
323
- Self :: wrap_arrow_function ( expr, ctx)
329
+ Self :: wrap_arrow_function_iife ( expr, ctx)
324
330
} else {
325
331
// Unfortunately no way to get compiler to see that this branch is provably unreachable.
326
332
// We don't want to inline this function, to keep `enter_expression` as small as possible.
@@ -659,7 +665,6 @@ impl<'a> OptionalChaining<'a, '_> {
659
665
let assignment_expression =
660
666
Self :: create_assignment_expression ( temp_binding. create_write_target ( ctx) , expr, ctx) ;
661
667
662
- let reference = temp_binding. create_read_expression ( ctx) ;
663
668
// `left || (binding = expr) === null`
664
669
let left = Self :: create_logical_expression (
665
670
left,
@@ -670,6 +675,7 @@ impl<'a> OptionalChaining<'a, '_> {
670
675
if self . ctx . assumptions . no_document_all {
671
676
left
672
677
} else {
678
+ let reference = temp_binding. create_read_expression ( ctx) ;
673
679
// `left || (binding = expr) === null || binding === void 0`
674
680
Self :: create_logical_expression ( left, Self :: wrap_void0_check ( reference, ctx) , ctx)
675
681
}
0 commit comments