Skip to content

Commit 06b6eb9

Browse files
authored
fix(es/compat): Generate OptCall for OptCall for private fields (#8031)
**Related issue:** - Closes #8003
1 parent 7f91274 commit 06b6eb9

File tree

5 files changed

+69
-21
lines changed

5 files changed

+69
-21
lines changed

crates/swc/tests/tsc-references/privateNameFieldCallExpression.1.normal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class A {
88
var _class_private_field_get1;
99
var _this_getInstance;
1010
_class_private_field_get(this, _fieldFunc).call(this);
11-
((_class_private_field_get1 = _class_private_field_get(this, _fieldFunc)) === null || _class_private_field_get1 === void 0 ? void 0 : _class_private_field_get1.call)(this);
11+
(_class_private_field_get1 = _class_private_field_get(this, _fieldFunc)) === null || _class_private_field_get1 === void 0 ? void 0 : _class_private_field_get1.call(this);
1212
const func = _class_private_field_get(this, _fieldFunc);
1313
func();
1414
new (_class_private_field_get(this, _fieldFunc))();

crates/swc/tests/tsc-references/privateNameStaticFieldCallExpression.1.normal.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class A {
44
test() {
55
var _class_static_private_field_spec_get1;
66
_class_static_private_field_spec_get(A, A, _fieldFunc).call(A);
7-
((_class_static_private_field_spec_get1 = _class_static_private_field_spec_get(A, A, _fieldFunc)) === null || _class_static_private_field_spec_get1 === void 0 ? void 0 : _class_static_private_field_spec_get1.call)(A);
7+
(_class_static_private_field_spec_get1 = _class_static_private_field_spec_get(A, A, _fieldFunc)) === null || _class_static_private_field_spec_get1 === void 0 ? void 0 : _class_static_private_field_spec_get1.call(A);
88
const func = _class_static_private_field_spec_get(A, A, _fieldFunc);
99
func();
1010
new (_class_static_private_field_spec_get(A, A, _fieldFunc))();

crates/swc_ecma_transforms_base/src/fixer.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,18 +101,16 @@ impl Fixer<'_> {
101101
}
102102

103103
fn wrap_callee(&mut self, e: &mut Expr) {
104-
if match e {
105-
Expr::Lit(Lit::Num(..) | Lit::Str(..)) => false,
104+
match e {
105+
Expr::Lit(Lit::Num(..) | Lit::Str(..)) => (),
106106
Expr::Cond(..)
107107
| Expr::Bin(..)
108108
| Expr::Lit(..)
109109
| Expr::Unary(..)
110110
| Expr::Object(..)
111111
| Expr::Await(..)
112-
| Expr::Yield(..) => true,
113-
_ => false,
114-
} {
115-
self.wrap(e)
112+
| Expr::Yield(..) => self.wrap(e),
113+
_ => (),
116114
}
117115
}
118116
}
@@ -400,7 +398,11 @@ impl VisitMut for Fixer<'_> {
400398
fn visit_mut_call_expr(&mut self, node: &mut CallExpr) {
401399
let old = self.visit_call(&mut node.args, &mut node.callee);
402400
if let Callee::Expr(e) = &mut node.callee {
403-
self.wrap_callee(e)
401+
if let Expr::OptChain(_) = &**e {
402+
self.wrap(e)
403+
} else {
404+
self.wrap_callee(e)
405+
}
404406
}
405407

406408
self.ctx = old;

crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -455,21 +455,28 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
455455
let (expr, this) = self.visit_mut_private_get(&mut callee, None);
456456
if let Some(this) = this {
457457
let args = iter::once(this.as_arg()).chain(call.args.take()).collect();
458-
*e = Expr::Call(CallExpr {
458+
let call = OptCall {
459459
span: *span,
460-
callee: OptChainExpr {
461-
span: *span,
462-
optional: *optional,
463-
base: Box::new(OptChainBase::Member(MemberExpr {
464-
span: call.span,
465-
obj: Box::new(expr),
466-
prop: MemberProp::Ident(quote_ident!("call")),
467-
})),
468-
}
469-
.as_callee(),
460+
callee: Box::new(
461+
OptChainExpr {
462+
span: *span,
463+
optional: *optional,
464+
base: Box::new(OptChainBase::Member(MemberExpr {
465+
span: call.span,
466+
obj: Box::new(expr),
467+
prop: MemberProp::Ident(quote_ident!("call")),
468+
})),
469+
}
470+
.into(),
471+
),
470472
args,
471473
type_args: call.type_args.take(),
472-
});
474+
};
475+
*e = Expr::OptChain(OptChainExpr {
476+
span: *span,
477+
optional: false,
478+
base: Box::new(OptChainBase::Call(call)),
479+
})
473480
} else {
474481
call.callee = Box::new(expr);
475482
}

crates/swc_ecma_transforms_compat/tests/es2022_class_properties.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use swc_ecma_transforms_compat::{
99
es2015::{arrow, block_scoping, classes, function_name, template_literal},
1010
es2016::exponentiation,
1111
es2017::async_to_generator,
12+
es2020::optional_chaining,
1213
es2022::class_properties,
1314
es3::reserved_words,
1415
};
@@ -6669,3 +6670,41 @@ var _x = {
66696670
};
66706671
"#
66716672
);
6673+
6674+
test!(
6675+
syntax(),
6676+
|t| {
6677+
let unresolved = Mark::new();
6678+
chain!(
6679+
class_properties(Some(t.comments.clone()), Default::default()),
6680+
optional_chaining(Default::default(), unresolved)
6681+
)
6682+
},
6683+
issue_8003,
6684+
"
6685+
class Foo {
6686+
#priv
6687+
search() {
6688+
this.#priv?.()
6689+
}
6690+
}
6691+
6692+
console.log(new Foo().search())",
6693+
r#"
6694+
var _priv = new WeakMap();
6695+
class Foo {
6696+
search() {
6697+
var _class_private_field_get1;
6698+
(_class_private_field_get1 = _class_private_field_get(this, _priv)) === null || _class_private_field_get1 === void 0 ? void 0 : _class_private_field_get1.call(this);
6699+
}
6700+
constructor(){
6701+
_class_private_field_init(this, _priv, {
6702+
writable: true,
6703+
value: void 0
6704+
});
6705+
}
6706+
}
6707+
6708+
console.log(new Foo().search());
6709+
"#
6710+
);

0 commit comments

Comments
 (0)