mirror of
https://github.com/swc-project/swc.git
synced 2024-10-04 12:18:08 +03:00
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.
This commit is contained in:
parent
512559818f
commit
7053bb16ce
@ -425,6 +425,8 @@ static RESSERVED_IN_STRICT_MODE: phf::Set<&str> = phf_set!(
|
||||
"yield",
|
||||
);
|
||||
|
||||
static RESSERVED_IN_STRICT_BIND: phf::Set<&str> = phf_set!("eval", "arguments",);
|
||||
|
||||
static RESERVED_IN_ES3: phf::Set<&str> = phf_set!(
|
||||
"abstract",
|
||||
"boolean",
|
||||
@ -457,12 +459,19 @@ pub trait IdentExt: AsRef<str> {
|
||||
}
|
||||
|
||||
fn is_reserved_in_strict_bind(&self) -> bool {
|
||||
["eval", "arguments"].contains(&self.as_ref())
|
||||
RESSERVED_IN_STRICT_BIND.contains(self.as_ref())
|
||||
}
|
||||
|
||||
fn is_reserved_in_es3(&self) -> bool {
|
||||
RESERVED_IN_ES3.contains(self.as_ref())
|
||||
}
|
||||
|
||||
fn is_reserved_in_any(&self) -> bool {
|
||||
RESERVED.contains(self.as_ref())
|
||||
|| RESSERVED_IN_STRICT_MODE.contains(self.as_ref())
|
||||
|| RESSERVED_IN_STRICT_BIND.contains(self.as_ref())
|
||||
|| RESERVED_IN_ES3.contains(self.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
impl IdentExt for Atom {}
|
||||
|
@ -1,9 +1,6 @@
|
||||
use swc_common::{
|
||||
collections::{AHashMap, AHashSet},
|
||||
comments::Comments,
|
||||
errors::HANDLER,
|
||||
util::take::Take,
|
||||
Mark, Span, Spanned, SyntaxContext, DUMMY_SP,
|
||||
collections::AHashMap, comments::Comments, errors::HANDLER, util::take::Take, Mark, Span,
|
||||
Spanned, SyntaxContext, DUMMY_SP,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_transforms_base::{helper, perf::Check};
|
||||
@ -530,7 +527,6 @@ impl<C: Comments> ClassProperties<C> {
|
||||
let mut super_ident = None;
|
||||
|
||||
class.body.visit_mut_with(&mut BrandCheckHandler {
|
||||
names: &mut AHashSet::default(),
|
||||
private: &self.private,
|
||||
});
|
||||
|
||||
@ -806,7 +802,13 @@ impl<C: Comments> ClassProperties<C> {
|
||||
match method.kind {
|
||||
MethodKind::Getter => format!("get_{}", method.key.id.sym).into(),
|
||||
MethodKind::Setter => format!("set_{}", method.key.id.sym).into(),
|
||||
MethodKind::Method => method.key.id.sym.clone(),
|
||||
MethodKind::Method => {
|
||||
if method.key.id.is_reserved_in_any() {
|
||||
format!("__{}", method.key.id.sym).into()
|
||||
} else {
|
||||
method.key.id.sym.clone()
|
||||
}
|
||||
}
|
||||
},
|
||||
method
|
||||
.span
|
||||
|
@ -2,10 +2,8 @@ use std::iter;
|
||||
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{
|
||||
collections::{AHashMap, AHashSet},
|
||||
errors::HANDLER,
|
||||
util::take::Take,
|
||||
Mark, Spanned, SyntaxContext, DUMMY_SP,
|
||||
collections::AHashMap, errors::HANDLER, util::take::Take, Mark, Spanned, SyntaxContext,
|
||||
DUMMY_SP,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_transforms_base::helper;
|
||||
@ -83,9 +81,6 @@ impl PrivateKind {
|
||||
}
|
||||
|
||||
pub(super) struct BrandCheckHandler<'a> {
|
||||
/// Private names used for brand checks.
|
||||
pub names: &'a mut AHashSet<JsWord>,
|
||||
|
||||
pub private: &'a PrivateRecord,
|
||||
}
|
||||
|
||||
@ -117,8 +112,6 @@ impl VisitMut for BrandCheckHandler<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
self.names.insert(n.id.sym.clone());
|
||||
|
||||
let (mark, kind, class_name) = self.private.get(&n.id);
|
||||
|
||||
if mark == Mark::root() {
|
||||
@ -596,7 +589,11 @@ impl<'a> PrivateAccessVisitor<'a> {
|
||||
}
|
||||
|
||||
let method_name = Ident::new(
|
||||
n.id.sym.clone(),
|
||||
if n.id.is_reserved_in_any() {
|
||||
format!("__{}", n.id.sym).into()
|
||||
} else {
|
||||
n.id.sym.clone()
|
||||
},
|
||||
n.id.span.with_ctxt(SyntaxContext::empty()).apply_mark(mark),
|
||||
);
|
||||
let ident = Ident::new(format!("_{}", n.id.sym).into(), n.id.span.apply_mark(mark));
|
||||
|
@ -0,0 +1,24 @@
|
||||
var _switch = /*#__PURE__*/ _class_private_field_loose_key("_switch"), _bar = /*#__PURE__*/ _class_private_field_loose_key("_bar");
|
||||
class TestCls {
|
||||
foo() {
|
||||
_class_private_field_loose_base(this, _bar)[_bar]();
|
||||
_class_private_field_loose_base(this, _switch)[_switch]();
|
||||
}
|
||||
constructor(){
|
||||
Object.defineProperty(this, _switch, {
|
||||
value: __switch
|
||||
});
|
||||
Object.defineProperty(this, _bar, {
|
||||
value: bar
|
||||
});
|
||||
}
|
||||
}
|
||||
function __switch() {
|
||||
console.log("#switch called");
|
||||
}
|
||||
function bar() {
|
||||
console.log("#bar called");
|
||||
}
|
||||
export { TestCls };
|
||||
let a = new TestCls;
|
||||
a.foo();
|
@ -0,0 +1,16 @@
|
||||
class TestCls {
|
||||
foo() {
|
||||
this.#bar();
|
||||
this.#switch();
|
||||
}
|
||||
#switch() {
|
||||
console.log("#switch called");
|
||||
}
|
||||
|
||||
#bar() {
|
||||
console.log("#bar called");
|
||||
}
|
||||
}
|
||||
|
||||
let a = new TestCls();
|
||||
a.foo();
|
@ -0,0 +1,19 @@
|
||||
var _switch = /*#__PURE__*/ new WeakSet(), _bar = /*#__PURE__*/ new WeakSet();
|
||||
class TestCls {
|
||||
foo() {
|
||||
_class_private_method_get(this, _bar, bar).call(this);
|
||||
_class_private_method_get(this, _switch, __switch).call(this);
|
||||
}
|
||||
constructor(){
|
||||
_class_private_method_init(this, _switch);
|
||||
_class_private_method_init(this, _bar);
|
||||
}
|
||||
}
|
||||
function __switch() {
|
||||
console.log("#switch called");
|
||||
}
|
||||
function bar() {
|
||||
console.log("#bar called");
|
||||
}
|
||||
let a = new TestCls();
|
||||
a.foo();
|
@ -4831,6 +4831,46 @@ class Cl {
|
||||
"#
|
||||
);
|
||||
|
||||
test!(
|
||||
syntax(),
|
||||
|t| {
|
||||
let unresolved_mark = Mark::new();
|
||||
let top_level_mark = Mark::new();
|
||||
|
||||
chain!(
|
||||
resolver(unresolved_mark, top_level_mark, false),
|
||||
class_properties(
|
||||
Some(t.comments.clone()),
|
||||
class_properties::Config {
|
||||
private_as_properties: true,
|
||||
..Default::default()
|
||||
},
|
||||
unresolved_mark,
|
||||
)
|
||||
)
|
||||
},
|
||||
loose_keyword_method,
|
||||
r##"
|
||||
class TestCls{
|
||||
foo(){
|
||||
this.#bar()
|
||||
this.#switch()
|
||||
}
|
||||
#switch(){
|
||||
console.log("#switch called")
|
||||
}
|
||||
|
||||
#bar(){
|
||||
console.log("#bar called")
|
||||
}
|
||||
}
|
||||
export {TestCls}
|
||||
|
||||
let a = new TestCls
|
||||
a.foo()
|
||||
"##
|
||||
);
|
||||
|
||||
#[testing::fixture("tests/classes/**/exec.js")]
|
||||
fn exec(input: PathBuf) {
|
||||
let src = read_to_string(input).unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user