Repository: swc-project/swc (rust)

Issue:
panic with 'assertion failed: self.vars.is_empty()'
### Describe the bug

I got a following panic
```
$ SWC_DEBUG=1 swc --sync foo.ts
Panic: PanicInfo { payload: Any { .. }, message: Some(assertion failed: self.vars.is_empty()), location: Location { file: "crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs", line: 131, col: 5 } }
Backtrace:    0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: <unknown>
   7: <unknown>
   8: <unknown>
   9: <unknown>
  10: <unknown>
  11: <unknown>
  12: <unknown>
  13: <unknown>
  14: <unknown>
  15: <unknown>
  16: <unknown>
  17: _ZN2v88internal25FunctionCallbackArguments4CallENS0_15CallHandlerInfoE
  18: <unknown>
  19: <unknown>
  20: _ZN2v88internal21Builtin_HandleApiCallEiPmPNS0_7IsolateE
  21: <unknown>

failed to handle: assertion failed: self.vars.is_empty()
Error: Failed to compile 1 file with swc.
    at Object.assertCompilationResult ($HOME/nodejs/lib/node_modules/@swc/cli/lib/swc/util.js:115:15)
    at files ($HOME/nodejs/lib/node_modules/@swc/cli/lib/swc/file.js:175:18)
```

with following `foo.ts`.
```
class A {
  B() {
    1;
    C.#D++;
    E(function() {});
  }
}
```

### Input code

_No response_

### Config

_No response_

### Playground link

_No response_

### Expected behavior

Do not panic.

### Actual behavior

_No response_

### Version

@swc/cli: 0.1.55 @swc/core: 1.2.128

### Additional context

_No response_

Pull request description:
fix(ecma/transform/compat): handle nest function in `private_field`
**Related issue (if exists):**
closes #3229 


Patch:
diff --git a/crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs b/crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs
index a66cecc835..0fc310f7e2 100644
--- a/crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs
+++ b/crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs
@@ -1,4 +1,4 @@
-use std::{iter, mem};
+use std::iter;
 use swc_atoms::JsWord;
 use swc_common::{collections::AHashSet, util::take::Take, Mark, Spanned, SyntaxContext, DUMMY_SP};
 use swc_ecma_ast::*;
@@ -98,7 +98,8 @@ pub(super) struct FieldAccessFolder<'a> {
 macro_rules! take_vars {
     ($name:ident, $T:tt) => {
         fn $name(&mut self, f: &mut $T) {
-            assert!(self.vars.is_empty());
+            let old_var = self.vars.take();
+
             if f.body.is_none() {
                 return;
             }
@@ -111,12 +112,14 @@ macro_rules! take_vars {
                     Stmt::Decl(Decl::Var(VarDecl {
                         span: DUMMY_SP,
                         kind: VarDeclKind::Var,
-                        decls: mem::take(&mut self.vars),
+                        decls: self.vars.take(),
 
                         declare: false,
                     })),
                 )
             }
+
+            self.vars = old_var;
         }
     };
 }


Test patch:
diff --git a/crates/swc_ecma_transforms_compat/tests/es2022_class_properties.rs b/crates/swc_ecma_transforms_compat/tests/es2022_class_properties.rs
index 52494584d1..ae43ef539a 100644
--- a/crates/swc_ecma_transforms_compat/tests/es2022_class_properties.rs
+++ b/crates/swc_ecma_transforms_compat/tests/es2022_class_properties.rs
@@ -5632,6 +5632,57 @@ test!(
     "
 );
 
+test!(
+    syntax(),
+    |_| class_properties(class_properties::Config { loose: false }),
+    issue_3229_1,
+    "
+class A {
+  B() {
+    1;
+    C.#D++;
+    E(function() {});
+  }
+}
+  ",
+    "
+class A {
+    B() {
+        var _C, _this_D;
+        1;
+        _classPrivateFieldSet(_C = C, _D, (_this_D = +_classPrivateFieldGet(_C, _D)) + 1), _this_D;
+        E(function() {});
+    }
+}
+  "
+);
+
+test!(
+    syntax(),
+    |_| class_properties(class_properties::Config { loose: false }),
+    issue_3229_2,
+    "
+class A {
+    foo() {
+        A.#b += 123
+        class B {
+            foo() {}
+        }
+    }
+}
+",
+    "
+class A {
+    foo() {
+        var _A;
+        _classPrivateFieldSet(_A = A, _b, _classPrivateFieldGet(_A, _b) + 123);
+        class B {
+            foo() {}
+        }
+    }
+}
+"
+);
 #[testing::fixture("tests/fixture/classes/**/exec.js")]
 fn exec(input: PathBuf) {
     let src = read_to_string(&input).unwrap();