Skip to content

Commit 8883968

Browse files
committed
refactor(transformer/class-properties): use duplicate_object in transform_expression_to_wrap_nullish_check (#7664)
The `duplicate_object` is great, it has handled unbound identifiers and `this` expressions, so we can remove a lot of code. But it is still a little bit annoying because we need two `object` here, although we can use `clone_in` it needs a special logic for `Expression::Identifier`.
1 parent f029090 commit 8883968

1 file changed

Lines changed: 14 additions & 39 deletions

File tree

  • crates/oxc_transformer/src/es2022/class_properties

crates/oxc_transformer/src/es2022/class_properties/private.rs

Lines changed: 14 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
44
use std::mem;
55

6-
use oxc_allocator::Box as ArenaBox;
6+
use oxc_allocator::{Box as ArenaBox, CloneIn};
77
use oxc_ast::{ast::*, NONE};
88
use oxc_span::SPAN;
99
use oxc_syntax::{
@@ -1102,34 +1102,26 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
11021102
///
11031103
/// Returns:
11041104
/// * Bound Identifier: `A` -> `A === null || A === void 0`
1105+
/// * `this`: `this` -> `this === null || this === void 0`
11051106
/// * Unbound Identifier or anything else: `A.B` -> `(_A$B = A.B) === null || _A$B === void 0`
11061107
///
1107-
/// NOTE: This method will mutate the passed-in `object` to a temp variable identifier.
1108+
/// NOTE: This method will mutate the passed-in `object` to a second copy of
1109+
/// [`Self::duplicate_object`]'s return.
11081110
fn transform_expression_to_wrap_nullish_check(
11091111
&mut self,
11101112
object: &mut Expression<'a>,
11111113
ctx: &mut TraverseCtx<'a>,
11121114
) -> Expression<'a> {
1113-
// `A` -> `A === null || A === void 0`
1114-
if let Expression::Identifier(ident) = object {
1115-
if let Some(binding) = self.get_existing_binding_for_identifier(ident, ctx) {
1116-
let left1 = binding.create_read_expression(ctx);
1117-
let left2 = binding.create_read_expression(ctx);
1118-
return self.wrap_nullish_check(left1, left2, ctx);
1119-
}
1120-
}
1121-
1122-
// `A.B` -> `(_A$B = A.B) === null || _A$B === void 0`
1123-
// TODO: should add an API `generate_uid_in_current_hoist_scope_based_on_node` to instead this
1124-
let temp_var_binding = self.ctx.var_declarations.create_uid_var_based_on_node(object, ctx);
1125-
1126-
let object = mem::replace(object, temp_var_binding.create_read_expression(ctx));
1127-
let assignment = create_assignment(
1128-
&temp_var_binding,
1129-
Self::ensure_optional_expression_wrapped_by_chain_expression(object, ctx),
1130-
ctx,
1131-
);
1132-
let reference = temp_var_binding.create_read_expression(ctx);
1115+
let owned_object = ctx.ast.move_expression(object.get_inner_expression_mut());
1116+
let owned_object =
1117+
Self::ensure_optional_expression_wrapped_by_chain_expression(owned_object, ctx);
1118+
let (assignment, reference) = self.duplicate_object(owned_object, ctx);
1119+
// We cannot use `clone_in` to clone identifier reference because it will lose reference id
1120+
*object = if let Expression::Identifier(ident) = &reference {
1121+
MaybeBoundIdentifier::from_identifier_reference(ident, ctx).create_read_expression(ctx)
1122+
} else {
1123+
reference.clone_in(ctx.ast.allocator)
1124+
};
11331125
self.wrap_nullish_check(assignment, reference, ctx)
11341126
}
11351127

@@ -1159,23 +1151,6 @@ impl<'a, 'ctx> ClassProperties<'a, 'ctx> {
11591151
}
11601152
}
11611153

1162-
/// Get an MaybeBoundIdentifier from an bound identifier reference.
1163-
///
1164-
/// If no temp variable required, returns `MaybeBoundIdentifier` for existing variable/global.
1165-
/// If temp variable is required, returns `None`.
1166-
fn get_existing_binding_for_identifier(
1167-
&self,
1168-
ident: &IdentifierReference<'a>,
1169-
ctx: &TraverseCtx<'a>,
1170-
) -> Option<MaybeBoundIdentifier<'a>> {
1171-
let binding = MaybeBoundIdentifier::from_identifier_reference(ident, ctx);
1172-
if self.ctx.assumptions.pure_getters || binding.to_bound_identifier().is_some() {
1173-
Some(binding)
1174-
} else {
1175-
None
1176-
}
1177-
}
1178-
11791154
/// Ensure that the expression is wrapped by a chain expression.
11801155
///
11811156
/// If the given expression contains optional expression, it will be wrapped by

0 commit comments

Comments
 (0)