Skip to content

Commit

Permalink
fix(es/compat): Fix handling of private members in optional chaining …
Browse files Browse the repository at this point in the history
…pass (swc-project#7610)

**Related issue:**

 - Closes swc-project#7561.
  • Loading branch information
komyg authored Jul 28, 2023
1 parent e105f20 commit 7ba7b6e
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 2 deletions.
49 changes: 47 additions & 2 deletions crates/swc_ecma_transforms_compat/src/es2020/optional_chaining.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::mem;

use serde::Deserialize;
use swc_atoms::js_word;
use swc_common::{util::take::Take, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_utils::{
Expand Down Expand Up @@ -181,7 +182,13 @@ impl OptChaining {
next = m.obj.take();
m.prop.visit_mut_with(self);
chain.push(if optional {
Gathering::OptMember(m.take(), self.memoize(&next))
match *next {
Expr::This(_) => Gathering::OptMember(
m.take(),
Ident::new(js_word!("this"), DUMMY_SP),
),
_ => Gathering::OptMember(m.take(), self.memoize(&next)),
}
} else {
Gathering::Member(m.take())
});
Expand Down Expand Up @@ -299,7 +306,11 @@ impl OptChaining {
Gathering::OptMember(mut m, memo) => {
committed_cond.push(CondExpr {
span: DUMMY_SP,
test: init_and_eq_null_or_undefined(&memo, current, no_document_all),
test: if memo.sym == js_word!("this") {
eq_null_or_undefined(&memo, no_document_all)
} else {
init_and_eq_null_or_undefined(&memo, current, no_document_all)
},
cons: if is_delete {
true.into()
} else {
Expand Down Expand Up @@ -409,3 +420,37 @@ fn init_and_eq_null_or_undefined(i: &Ident, init: Expr, no_document_all: bool) -
right: void_cmp,
}))
}

fn eq_null_or_undefined(i: &Ident, no_document_all: bool) -> Box<Expr> {
let lhs = Box::new(Expr::Ident(i.clone()));

if no_document_all {
return Box::new(Expr::Bin(BinExpr {
span: DUMMY_SP,
left: lhs,
op: op!("=="),
right: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
}));
}

let null_cmp = Box::new(Expr::Bin(BinExpr {
span: DUMMY_SP,
left: lhs,
op: op!("==="),
right: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
}));

let void_cmp = Box::new(Expr::Bin(BinExpr {
span: DUMMY_SP,
left: Box::new(Expr::Ident(i.clone())),
op: op!("==="),
right: undefined(DUMMY_SP),
}));

Box::new(Expr::Bin(BinExpr {
span: DUMMY_SP,
left: null_cmp,
op: op!("||"),
right: void_cmp,
}))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class Foo {
#x;

test() {
this?.y.#x;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Foo {
#x;
test() {
this === null || this === void 0 ? void 0 : this.y.#x;
}
}

0 comments on commit 7ba7b6e

Please sign in to comment.