Skip to content

Commit 1976c93

Browse files
committed
refactor(transformer): nullish coalescing transform: no cloning identifier references
1 parent b9691dc commit 1976c93

File tree

1 file changed

+12
-26
lines changed

1 file changed

+12
-26
lines changed

crates/oxc_transformer/src/es2020/nullish_coalescing_operator.rs

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
3131
use oxc_allocator::CloneIn;
3232
use oxc_ast::{ast::*, NONE};
33-
use oxc_semantic::{ReferenceFlags, ScopeFlags, ScopeId, SymbolFlags};
33+
use oxc_semantic::{ReferenceFlags, ScopeFlags, SymbolFlags};
3434
use oxc_span::SPAN;
3535
use oxc_syntax::operator::{AssignmentOperator, BinaryOperator, LogicalOperator};
3636
use oxc_traverse::{Ancestor, Traverse, TraverseCtx};
@@ -84,28 +84,33 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> {
8484
ctx.current_scope_id()
8585
};
8686

87-
let (id, ident) =
88-
Self::create_new_var_with_expression(&logical_expr.left, current_scope_id, ctx);
87+
// Add `var _name` to scope
88+
let binding = ctx.generate_uid_based_on_node(
89+
&logical_expr.left,
90+
current_scope_id,
91+
SymbolFlags::FunctionScopedVariable,
92+
);
8993

9094
let left =
9195
AssignmentTarget::from(ctx.ast.simple_assignment_target_from_identifier_reference(
92-
ctx.clone_identifier_reference(&ident, ReferenceFlags::read_write()),
96+
binding.create_read_write_reference(ctx),
9397
));
9498

95-
let reference = ctx.ast.expression_from_identifier_reference(ident);
99+
let reference =
100+
ctx.ast.expression_from_identifier_reference(binding.create_read_reference(ctx));
96101
let assignment = ctx.ast.expression_assignment(
97102
SPAN,
98103
AssignmentOperator::Assign,
99104
left,
100105
logical_expr.left,
101106
);
102-
103107
let mut new_expr =
104108
Self::create_conditional_expression(reference, assignment, logical_expr.right, ctx);
105109

106110
if is_parent_formal_parameter {
107111
// Replace `function (a, x = a.b ?? c) {}` to `function (a, x = (() => a.b ?? c)() ){}`
108112
// so the temporary variable can be injected in correct scope
113+
let id = binding.create_binding_pattern(ctx);
109114
let param = ctx.ast.formal_parameter(SPAN, ctx.ast.vec(), id, None, false, false);
110115
let params = ctx.ast.formal_parameters(
111116
SPAN,
@@ -125,7 +130,7 @@ impl<'a, 'ctx> Traverse<'a> for NullishCoalescingOperator<'a, 'ctx> {
125130
// `(x) => x;` -> `((x) => x)();`
126131
new_expr = ctx.ast.expression_call(SPAN, arrow_function, NONE, ctx.ast.vec(), false);
127132
} else {
128-
self.ctx.var_declarations.insert_binding_pattern(id, None, ctx);
133+
self.ctx.var_declarations.insert(&binding, None, ctx);
129134
}
130135

131136
*expr = new_expr;
@@ -142,25 +147,6 @@ impl<'a, 'ctx> NullishCoalescingOperator<'a, 'ctx> {
142147
}
143148
}
144149

145-
fn create_new_var_with_expression(
146-
expr: &Expression<'a>,
147-
current_scope_id: ScopeId,
148-
ctx: &mut TraverseCtx<'a>,
149-
) -> (BindingPattern<'a>, IdentifierReference<'a>) {
150-
// Add `var name` to scope
151-
let binding = ctx.generate_uid_based_on_node(
152-
expr,
153-
current_scope_id,
154-
SymbolFlags::FunctionScopedVariable,
155-
);
156-
157-
// var _name;
158-
let id = binding.create_binding_pattern(ctx);
159-
160-
let reference = binding.create_read_reference(ctx);
161-
(id, reference)
162-
}
163-
164150
/// Create a conditional expression
165151
///
166152
/// ```js

0 commit comments

Comments
 (0)