From 40ecff754f59cbbe919398092eae47b3a847e1be Mon Sep 17 00:00:00 2001 From: magic-akari Date: Tue, 26 Mar 2024 11:29:01 +0800 Subject: [PATCH 1/3] fix(es/compat): Handle TDZ correctly --- .../src/class_properties/class_name_tdz.rs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/crates/swc_ecma_compat_es2022/src/class_properties/class_name_tdz.rs b/crates/swc_ecma_compat_es2022/src/class_properties/class_name_tdz.rs index 98609fb28169..bbae4845f2b8 100644 --- a/crates/swc_ecma_compat_es2022/src/class_properties/class_name_tdz.rs +++ b/crates/swc_ecma_compat_es2022/src/class_properties/class_name_tdz.rs @@ -13,6 +13,45 @@ pub(super) struct ClassNameTdzFolder<'a> { impl<'a> VisitMut for ClassNameTdzFolder<'a> { noop_visit_mut_type!(); + noop_visit_mut_type!(visit_mut_function, Function); + + fn visit_mut_class_member(&mut self, n: &mut ClassMember) { + match n { + ClassMember::Method(ClassMethod { + key: PropName::Computed(computed), + .. + }) + | ClassMember::ClassProp(ClassProp { + key: PropName::Computed(computed), + .. + }) => { + computed.visit_mut_with(self); + } + _ => {} + } + } + + fn visit_mut_prop(&mut self, n: &mut Prop) { + match n { + Prop::KeyValue(..) => { + n.visit_mut_children_with(self); + } + Prop::Getter(GetterProp { + key: PropName::Computed(computed), + .. + }) + | Prop::Setter(SetterProp { + key: PropName::Computed(computed), + .. + }) + | Prop::Method(MethodProp { + key: PropName::Computed(computed), + .. + }) => computed.visit_mut_children_with(self), + _ => {} + } + } + fn visit_mut_expr(&mut self, expr: &mut Expr) { match expr { Expr::Ident(i) => { From 012e55ca4eb4f74fe6975d46e17eeb82d5e8afc5 Mon Sep 17 00:00:00 2001 From: magic-akari Date: Tue, 26 Mar 2024 11:29:13 +0800 Subject: [PATCH 2/3] chore: update test cases --- .../fixture/issues-8xxx/8776/input/.swcrc | 20 +++++++++++++++++++ .../fixture/issues-8xxx/8776/input/index.js | 6 ++++++ .../fixture/issues-8xxx/8776/output/index.js | 14 +++++++++++++ 3 files changed, 40 insertions(+) create mode 100644 crates/swc/tests/fixture/issues-8xxx/8776/input/.swcrc create mode 100644 crates/swc/tests/fixture/issues-8xxx/8776/input/index.js create mode 100644 crates/swc/tests/fixture/issues-8xxx/8776/output/index.js diff --git a/crates/swc/tests/fixture/issues-8xxx/8776/input/.swcrc b/crates/swc/tests/fixture/issues-8xxx/8776/input/.swcrc new file mode 100644 index 000000000000..a9659c1a402b --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8776/input/.swcrc @@ -0,0 +1,20 @@ +{ + "jsc": { + "parser": { + "syntax": "typescript", + "tsx": true, + "decorators": true + }, + "target": "es2021", + "loose": false, + "minify": { + "compress": false, + "mangle": false + } + }, + "module": { + "type": "es6" + }, + "minify": false, + "isModule": true +} \ No newline at end of file diff --git a/crates/swc/tests/fixture/issues-8xxx/8776/input/index.js b/crates/swc/tests/fixture/issues-8xxx/8776/input/index.js new file mode 100644 index 000000000000..5a634ae5f1a3 --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8776/input/index.js @@ -0,0 +1,6 @@ +let capturedPrivateAccess; +class A { + static #x = 42; + static [(class {}, (capturedPrivateAccess = () => A.#x))]; +} +console.log(capturedPrivateAccess()); diff --git a/crates/swc/tests/fixture/issues-8xxx/8776/output/index.js b/crates/swc/tests/fixture/issues-8xxx/8776/output/index.js new file mode 100644 index 000000000000..63b1c48da5cc --- /dev/null +++ b/crates/swc/tests/fixture/issues-8xxx/8776/output/index.js @@ -0,0 +1,14 @@ +import { _ as _class_name_tdz_error } from "@swc/helpers/_/_class_name_tdz_error"; +import { _ as _class_static_private_field_spec_get } from "@swc/helpers/_/_class_static_private_field_spec_get"; +import { _ as _define_property } from "@swc/helpers/_/_define_property"; +let capturedPrivateAccess; +let _ref = (class { +}, capturedPrivateAccess = ()=>_class_static_private_field_spec_get((_class_name_tdz_error("A"), A), A, _x)); +class A { +} +var _x = { + writable: true, + value: 42 +}; +_define_property(A, _ref, void 0); +console.log(capturedPrivateAccess()); From 2b9e73b0e22a273c478673d72e53aa165b9df76a Mon Sep 17 00:00:00 2001 From: magic-akari Date: Tue, 26 Mar 2024 12:06:39 +0800 Subject: [PATCH 3/3] fix(es/compat): bypass ArrowExpr in TDZ checker --- crates/swc/tests/fixture/issues-8xxx/8776/output/index.js | 3 +-- .../src/class_properties/class_name_tdz.rs | 2 ++ 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/swc/tests/fixture/issues-8xxx/8776/output/index.js b/crates/swc/tests/fixture/issues-8xxx/8776/output/index.js index 63b1c48da5cc..da59f108e51d 100644 --- a/crates/swc/tests/fixture/issues-8xxx/8776/output/index.js +++ b/crates/swc/tests/fixture/issues-8xxx/8776/output/index.js @@ -1,9 +1,8 @@ -import { _ as _class_name_tdz_error } from "@swc/helpers/_/_class_name_tdz_error"; import { _ as _class_static_private_field_spec_get } from "@swc/helpers/_/_class_static_private_field_spec_get"; import { _ as _define_property } from "@swc/helpers/_/_define_property"; let capturedPrivateAccess; let _ref = (class { -}, capturedPrivateAccess = ()=>_class_static_private_field_spec_get((_class_name_tdz_error("A"), A), A, _x)); +}, capturedPrivateAccess = ()=>_class_static_private_field_spec_get(A, A, _x)); class A { } var _x = { diff --git a/crates/swc_ecma_compat_es2022/src/class_properties/class_name_tdz.rs b/crates/swc_ecma_compat_es2022/src/class_properties/class_name_tdz.rs index bbae4845f2b8..a116a4381a98 100644 --- a/crates/swc_ecma_compat_es2022/src/class_properties/class_name_tdz.rs +++ b/crates/swc_ecma_compat_es2022/src/class_properties/class_name_tdz.rs @@ -15,6 +15,8 @@ impl<'a> VisitMut for ClassNameTdzFolder<'a> { noop_visit_mut_type!(visit_mut_function, Function); + noop_visit_mut_type!(visit_mut_arrow_expr, ArrowExpr); + fn visit_mut_class_member(&mut self, n: &mut ClassMember) { match n { ClassMember::Method(ClassMethod {