Skip to content

Commit 7053bb1

Browse files
authored
fix(es/compat): Avoid reserved name for private method (#8949)
**Description:** Following development should follow babel/babel#16261 to avoid separate `WeakMap` for each individual private method **Related issue:** - Closes #8948.
1 parent 5125598 commit 7053bb1

File tree

7 files changed

+125
-18
lines changed

7 files changed

+125
-18
lines changed

crates/swc_ecma_ast/src/ident.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,8 @@ static RESSERVED_IN_STRICT_MODE: phf::Set<&str> = phf_set!(
425425
"yield",
426426
);
427427

428+
static RESSERVED_IN_STRICT_BIND: phf::Set<&str> = phf_set!("eval", "arguments",);
429+
428430
static RESERVED_IN_ES3: phf::Set<&str> = phf_set!(
429431
"abstract",
430432
"boolean",
@@ -457,12 +459,19 @@ pub trait IdentExt: AsRef<str> {
457459
}
458460

459461
fn is_reserved_in_strict_bind(&self) -> bool {
460-
["eval", "arguments"].contains(&self.as_ref())
462+
RESSERVED_IN_STRICT_BIND.contains(self.as_ref())
461463
}
462464

463465
fn is_reserved_in_es3(&self) -> bool {
464466
RESERVED_IN_ES3.contains(self.as_ref())
465467
}
468+
469+
fn is_reserved_in_any(&self) -> bool {
470+
RESERVED.contains(self.as_ref())
471+
|| RESSERVED_IN_STRICT_MODE.contains(self.as_ref())
472+
|| RESSERVED_IN_STRICT_BIND.contains(self.as_ref())
473+
|| RESERVED_IN_ES3.contains(self.as_ref())
474+
}
466475
}
467476

468477
impl IdentExt for Atom {}

crates/swc_ecma_compat_es2022/src/class_properties/mod.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
use swc_common::{
2-
collections::{AHashMap, AHashSet},
3-
comments::Comments,
4-
errors::HANDLER,
5-
util::take::Take,
6-
Mark, Span, Spanned, SyntaxContext, DUMMY_SP,
2+
collections::AHashMap, comments::Comments, errors::HANDLER, util::take::Take, Mark, Span,
3+
Spanned, SyntaxContext, DUMMY_SP,
74
};
85
use swc_ecma_ast::*;
96
use swc_ecma_transforms_base::{helper, perf::Check};
@@ -530,7 +527,6 @@ impl<C: Comments> ClassProperties<C> {
530527
let mut super_ident = None;
531528

532529
class.body.visit_mut_with(&mut BrandCheckHandler {
533-
names: &mut AHashSet::default(),
534530
private: &self.private,
535531
});
536532

@@ -806,7 +802,13 @@ impl<C: Comments> ClassProperties<C> {
806802
match method.kind {
807803
MethodKind::Getter => format!("get_{}", method.key.id.sym).into(),
808804
MethodKind::Setter => format!("set_{}", method.key.id.sym).into(),
809-
MethodKind::Method => method.key.id.sym.clone(),
805+
MethodKind::Method => {
806+
if method.key.id.is_reserved_in_any() {
807+
format!("__{}", method.key.id.sym).into()
808+
} else {
809+
method.key.id.sym.clone()
810+
}
811+
}
810812
},
811813
method
812814
.span

crates/swc_ecma_compat_es2022/src/class_properties/private_field.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ use std::iter;
22

33
use swc_atoms::JsWord;
44
use swc_common::{
5-
collections::{AHashMap, AHashSet},
6-
errors::HANDLER,
7-
util::take::Take,
8-
Mark, Spanned, SyntaxContext, DUMMY_SP,
5+
collections::AHashMap, errors::HANDLER, util::take::Take, Mark, Spanned, SyntaxContext,
6+
DUMMY_SP,
97
};
108
use swc_ecma_ast::*;
119
use swc_ecma_transforms_base::helper;
@@ -83,9 +81,6 @@ impl PrivateKind {
8381
}
8482

8583
pub(super) struct BrandCheckHandler<'a> {
86-
/// Private names used for brand checks.
87-
pub names: &'a mut AHashSet<JsWord>,
88-
8984
pub private: &'a PrivateRecord,
9085
}
9186

@@ -117,8 +112,6 @@ impl VisitMut for BrandCheckHandler<'_> {
117112
}
118113
}
119114

120-
self.names.insert(n.id.sym.clone());
121-
122115
let (mark, kind, class_name) = self.private.get(&n.id);
123116

124117
if mark == Mark::root() {
@@ -596,7 +589,11 @@ impl<'a> PrivateAccessVisitor<'a> {
596589
}
597590

598591
let method_name = Ident::new(
599-
n.id.sym.clone(),
592+
if n.id.is_reserved_in_any() {
593+
format!("__{}", n.id.sym).into()
594+
} else {
595+
n.id.sym.clone()
596+
},
600597
n.id.span.with_ctxt(SyntaxContext::empty()).apply_mark(mark),
601598
);
602599
let ident = Ident::new(format!("_{}", n.id.sym).into(), n.id.span.apply_mark(mark));
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
var _switch = /*#__PURE__*/ _class_private_field_loose_key("_switch"), _bar = /*#__PURE__*/ _class_private_field_loose_key("_bar");
2+
class TestCls {
3+
foo() {
4+
_class_private_field_loose_base(this, _bar)[_bar]();
5+
_class_private_field_loose_base(this, _switch)[_switch]();
6+
}
7+
constructor(){
8+
Object.defineProperty(this, _switch, {
9+
value: __switch
10+
});
11+
Object.defineProperty(this, _bar, {
12+
value: bar
13+
});
14+
}
15+
}
16+
function __switch() {
17+
console.log("#switch called");
18+
}
19+
function bar() {
20+
console.log("#bar called");
21+
}
22+
export { TestCls };
23+
let a = new TestCls;
24+
a.foo();
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class TestCls {
2+
foo() {
3+
this.#bar();
4+
this.#switch();
5+
}
6+
#switch() {
7+
console.log("#switch called");
8+
}
9+
10+
#bar() {
11+
console.log("#bar called");
12+
}
13+
}
14+
15+
let a = new TestCls();
16+
a.foo();
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
var _switch = /*#__PURE__*/ new WeakSet(), _bar = /*#__PURE__*/ new WeakSet();
2+
class TestCls {
3+
foo() {
4+
_class_private_method_get(this, _bar, bar).call(this);
5+
_class_private_method_get(this, _switch, __switch).call(this);
6+
}
7+
constructor(){
8+
_class_private_method_init(this, _switch);
9+
_class_private_method_init(this, _bar);
10+
}
11+
}
12+
function __switch() {
13+
console.log("#switch called");
14+
}
15+
function bar() {
16+
console.log("#bar called");
17+
}
18+
let a = new TestCls();
19+
a.foo();

crates/swc_ecma_transforms_compat/tests/es2022_class_properties.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4831,6 +4831,46 @@ class Cl {
48314831
"#
48324832
);
48334833

4834+
test!(
4835+
syntax(),
4836+
|t| {
4837+
let unresolved_mark = Mark::new();
4838+
let top_level_mark = Mark::new();
4839+
4840+
chain!(
4841+
resolver(unresolved_mark, top_level_mark, false),
4842+
class_properties(
4843+
Some(t.comments.clone()),
4844+
class_properties::Config {
4845+
private_as_properties: true,
4846+
..Default::default()
4847+
},
4848+
unresolved_mark,
4849+
)
4850+
)
4851+
},
4852+
loose_keyword_method,
4853+
r##"
4854+
class TestCls{
4855+
foo(){
4856+
this.#bar()
4857+
this.#switch()
4858+
}
4859+
#switch(){
4860+
console.log("#switch called")
4861+
}
4862+
4863+
#bar(){
4864+
console.log("#bar called")
4865+
}
4866+
}
4867+
export {TestCls}
4868+
4869+
let a = new TestCls
4870+
a.foo()
4871+
"##
4872+
);
4873+
48344874
#[testing::fixture("tests/classes/**/exec.js")]
48354875
fn exec(input: PathBuf) {
48364876
let src = read_to_string(input).unwrap();

0 commit comments

Comments
 (0)