fix(es/compat): Generate OptCall for OptCall for private fields (#8031)

**Related issue:**

 - Closes #8003
This commit is contained in:
Austaras 2023-09-30 05:32:48 +08:00 committed by GitHub
parent 7f91274208
commit 06b6eb9999
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 69 additions and 21 deletions

View File

@ -8,7 +8,7 @@ class A {
var _class_private_field_get1; var _class_private_field_get1;
var _this_getInstance; var _this_getInstance;
_class_private_field_get(this, _fieldFunc).call(this); _class_private_field_get(this, _fieldFunc).call(this);
((_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); (_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);
const func = _class_private_field_get(this, _fieldFunc); const func = _class_private_field_get(this, _fieldFunc);
func(); func();
new (_class_private_field_get(this, _fieldFunc))(); new (_class_private_field_get(this, _fieldFunc))();

View File

@ -4,7 +4,7 @@ class A {
test() { test() {
var _class_static_private_field_spec_get1; var _class_static_private_field_spec_get1;
_class_static_private_field_spec_get(A, A, _fieldFunc).call(A); _class_static_private_field_spec_get(A, A, _fieldFunc).call(A);
((_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); (_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);
const func = _class_static_private_field_spec_get(A, A, _fieldFunc); const func = _class_static_private_field_spec_get(A, A, _fieldFunc);
func(); func();
new (_class_static_private_field_spec_get(A, A, _fieldFunc))(); new (_class_static_private_field_spec_get(A, A, _fieldFunc))();

View File

@ -101,18 +101,16 @@ impl Fixer<'_> {
} }
fn wrap_callee(&mut self, e: &mut Expr) { fn wrap_callee(&mut self, e: &mut Expr) {
if match e { match e {
Expr::Lit(Lit::Num(..) | Lit::Str(..)) => false, Expr::Lit(Lit::Num(..) | Lit::Str(..)) => (),
Expr::Cond(..) Expr::Cond(..)
| Expr::Bin(..) | Expr::Bin(..)
| Expr::Lit(..) | Expr::Lit(..)
| Expr::Unary(..) | Expr::Unary(..)
| Expr::Object(..) | Expr::Object(..)
| Expr::Await(..) | Expr::Await(..)
| Expr::Yield(..) => true, | Expr::Yield(..) => self.wrap(e),
_ => false, _ => (),
} {
self.wrap(e)
} }
} }
} }
@ -400,7 +398,11 @@ impl VisitMut for Fixer<'_> {
fn visit_mut_call_expr(&mut self, node: &mut CallExpr) { fn visit_mut_call_expr(&mut self, node: &mut CallExpr) {
let old = self.visit_call(&mut node.args, &mut node.callee); let old = self.visit_call(&mut node.args, &mut node.callee);
if let Callee::Expr(e) = &mut node.callee { if let Callee::Expr(e) = &mut node.callee {
self.wrap_callee(e) if let Expr::OptChain(_) = &**e {
self.wrap(e)
} else {
self.wrap_callee(e)
}
} }
self.ctx = old; self.ctx = old;

View File

@ -455,21 +455,28 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> {
let (expr, this) = self.visit_mut_private_get(&mut callee, None); let (expr, this) = self.visit_mut_private_get(&mut callee, None);
if let Some(this) = this { if let Some(this) = this {
let args = iter::once(this.as_arg()).chain(call.args.take()).collect(); let args = iter::once(this.as_arg()).chain(call.args.take()).collect();
*e = Expr::Call(CallExpr { let call = OptCall {
span: *span, span: *span,
callee: OptChainExpr { callee: Box::new(
span: *span, OptChainExpr {
optional: *optional, span: *span,
base: Box::new(OptChainBase::Member(MemberExpr { optional: *optional,
span: call.span, base: Box::new(OptChainBase::Member(MemberExpr {
obj: Box::new(expr), span: call.span,
prop: MemberProp::Ident(quote_ident!("call")), obj: Box::new(expr),
})), prop: MemberProp::Ident(quote_ident!("call")),
} })),
.as_callee(), }
.into(),
),
args, args,
type_args: call.type_args.take(), type_args: call.type_args.take(),
}); };
*e = Expr::OptChain(OptChainExpr {
span: *span,
optional: false,
base: Box::new(OptChainBase::Call(call)),
})
} else { } else {
call.callee = Box::new(expr); call.callee = Box::new(expr);
} }

View File

@ -9,6 +9,7 @@ use swc_ecma_transforms_compat::{
es2015::{arrow, block_scoping, classes, function_name, template_literal}, es2015::{arrow, block_scoping, classes, function_name, template_literal},
es2016::exponentiation, es2016::exponentiation,
es2017::async_to_generator, es2017::async_to_generator,
es2020::optional_chaining,
es2022::class_properties, es2022::class_properties,
es3::reserved_words, es3::reserved_words,
}; };
@ -6669,3 +6670,41 @@ var _x = {
}; };
"# "#
); );
test!(
syntax(),
|t| {
let unresolved = Mark::new();
chain!(
class_properties(Some(t.comments.clone()), Default::default()),
optional_chaining(Default::default(), unresolved)
)
},
issue_8003,
"
class Foo {
#priv
search() {
this.#priv?.()
}
}
console.log(new Foo().search())",
r#"
var _priv = new WeakMap();
class Foo {
search() {
var _class_private_field_get1;
(_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);
}
constructor(){
_class_private_field_init(this, _priv, {
writable: true,
value: void 0
});
}
}
console.log(new Foo().search());
"#
);