Repository: swc-project/swc (rust)

Issue:
Wrong "this" in async arrow function params
### Describe the bug

define an async arrow function property in the class . if the function param has a default value , the context "this" will reference error

### Input code

```typescript
export class CompanyBgStore {
  public corpName =123

  public getBusinessInfo = async(corpName=this.corpName) => {
    console.log(corpName)
  };
}
```


### Config

```json
{
  "jsc": {
    "externalHelpers": true,
    "parser": {
      "syntax": "typescript",
      "decorators": true,
      "tsx": true
    },
    "transform": {
      "legacyDecorator": true,
      "decoratorMetadata": false
    },
    "target": "es5",
    "loose": false,
    "minify": {
      "compress": false,
      "mangle": false
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": false,
  "isModule": true
}
```


### Playground link

https://play.swc.rs/?version=1.2.161&code=H4sIAAAAAAAAA0WMsQrCMBRF93zFHe1SUEeJQ51cXPoFaXjGQPpeyEvBUvrvFqE63nMPh95ZSoVPThU3GbPjuQt9lUJYDJCnIUUPLyU%2F3Eiwx9PZ%2FHmg2k0amVTv%2FBRYOJ3ZH3bf1lfUdl8N7PVbxRZklURtkvCTm%2B1ZL2Y1H%2FanAiWVAAAA&config=H4sIAAAAAAAAA0WOvQ6DMAyE38Uzaztk7tCFh7CCQanyJ9tIRIh3b5JC2U723Xe3w0csmB1oU%2BKI%2Fk0%2BEwsY5ZUGyMhC3AxSouIGBrRkEssuKwwwkU2Mmu6EyvaTR9WMUebEoQE8LWjL6wpc%2Fj9hJMUJFcHM6KXHkRfSWknyqF0%2BJaHzO0Bw0c2lgW0KmUnkfmFc%2FOU8KiikaW2HvY%2FvwCccN%2BPMORlPY9%2F%2FBaxpS4QcAQAA

### Expected behavior

import * as swcHelpers from "@swc/helpers";
import regeneratorRuntime from "regenerator-runtime";
export var CompanyBgStore = function CompanyBgStore() {
    "use strict";
    var _this = this;
    swcHelpers.classCallCheck(this, CompanyBgStore);
    this.corpName = 123;
    this.getBusinessInfo = swcHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee() {
        var corpName, _args = arguments;
        return regeneratorRuntime.wrap(function _callee$(_ctx) {
            while(1)switch(_ctx.prev = _ctx.next){
                case 0:
                    corpName = _args.length > 0 && _args[0] !== void 0 ? _args[0] : _this.corpName;
                    console.log(corpName);
                case 2:
                case "end":
                    return _ctx.stop();
            }
        }, _callee, this);
    }));
};


### Actual behavior

import * as swcHelpers from "@swc/helpers";
import regeneratorRuntime from "regenerator-runtime";
export var CompanyBgStore = function CompanyBgStore() {
    "use strict";
    swcHelpers.classCallCheck(this, CompanyBgStore);
    this.corpName = 123;
    this.getBusinessInfo = swcHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee() {
        var corpName, _args = arguments;
        return regeneratorRuntime.wrap(function _callee$(_ctx) {
            while(1)switch(_ctx.prev = _ctx.next){
                case 0:
                    corpName = _args.length > 0 && _args[0] !== void 0 ? _args[0] : this.corpName;
                    console.log(corpName);
                case 2:
                case "end":
                    return _ctx.stop();
            }
        }, _callee, this);
    }));
};


### Version

1.2.161

### Additional context

babel:
![image](https://user-images.githubusercontent.com/17813559/160986094-dad8018b-4483-4146-b1bb-375d5be6efbc.png)
swc:
![image](https://user-images.githubusercontent.com/17813559/160986153-7f22ec21-275c-45ea-8131-fe9e81047f68.png)


Pull request description:
fix(es/compat): hoist env in function params
<!-- Note: CI script will automatically rebase your PR so please do not rebase unless required -->

<!-- Thanks for submitting a pull request! Please provide enough information so that others can review your pull request. -->

**Description:**

<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->

**BREAKING CHANGE:**

<!--
If this PR introduces a breaking change, it must contain a notice for it to be included in the CHANGELOG. Add description or remove entirely if not breaking.

You may need to update `MIGRATION.md` for the breaking changes.
-->

**Related issue (if exists):**
- fix #4208 

Patch:
diff --git a/crates/swc_ecma_transforms_compat/src/es2017/async_to_generator.rs b/crates/swc_ecma_transforms_compat/src/es2017/async_to_generator.rs
index f269aaa578..9db920134e 100644
--- a/crates/swc_ecma_transforms_compat/src/es2017/async_to_generator.rs
+++ b/crates/swc_ecma_transforms_compat/src/es2017/async_to_generator.rs
@@ -309,7 +309,7 @@ impl Actual {
             Expr::Arrow(arrow_expr @ ArrowExpr { is_async: true, .. }) => {
                 let mut state = FnEnvHoister::default();
 
-                arrow_expr.body.visit_mut_with(&mut state);
+                arrow_expr.visit_mut_with(&mut state);
 
                 self.hoist_stmts.extend(state.to_stmt());
 


Test patch:
diff --git a/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/input/.swcrc b/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/input/.swcrc
new file mode 100644
index 0000000000..bbd07d8782
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/input/.swcrc
@@ -0,0 +1,24 @@
+{
+    "jsc": {
+        "externalHelpers": true,
+        "parser": {
+            "syntax": "typescript",
+            "decorators": true,
+            "tsx": true
+        },
+        "transform": {
+            "legacyDecorator": true,
+            "decoratorMetadata": false
+        },
+        "target": "es5",
+        "loose": false,
+        "minify": {
+            "compress": false,
+            "mangle": false
+        }
+    },
+    "module": {
+        "type": "es6"
+    },
+    "minify": false
+}
diff --git a/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/input/index.ts b/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/input/index.ts
new file mode 100644
index 0000000000..cffe10faac
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/input/index.ts
@@ -0,0 +1,7 @@
+export class CompanyBgStore {
+    public corpName = 123;
+
+    public getBusinessInfo = async (corpName = this.corpName) => {
+        console.log(corpName);
+    };
+}
diff --git a/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/output/index.ts b/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/output/index.ts
new file mode 100644
index 0000000000..8e55375b0a
--- /dev/null
+++ b/crates/swc/tests/fixture/issues-4xxx/issue-4208/1/output/index.ts
@@ -0,0 +1,21 @@
+import * as swcHelpers from "@swc/helpers";
+import regeneratorRuntime from "regenerator-runtime";
+export var CompanyBgStore = function CompanyBgStore() {
+    "use strict";
+    swcHelpers.classCallCheck(this, CompanyBgStore);
+    this.corpName = 123;
+    var _this = this;
+    this.getBusinessInfo = swcHelpers.asyncToGenerator(regeneratorRuntime.mark(function _callee() {
+        var corpName, _args = arguments;
+        return regeneratorRuntime.wrap(function _callee$(_ctx) {
+            while(1)switch(_ctx.prev = _ctx.next){
+                case 0:
+                    corpName = _args.length > 0 && _args[0] !== void 0 ? _args[0] : _this.corpName;
+                    console.log(corpName);
+                case 2:
+                case "end":
+                    return _ctx.stop();
+            }
+        }, _callee);
+    }));
+};
diff --git a/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs b/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs
index 2b1c79bdaa..c3df19604f 100644
--- a/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs
+++ b/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs
@@ -3557,6 +3557,32 @@ const p = Z((f)=>_asyncToGenerator(function*(n = 0) {
 "
 );
 
+test!(
+    Syntax::default(),
+    |_| async_to_generator(Default::default()),
+    issue_4208,
+    "
+    function foo() {
+        const bar = async (baz = this.baz) => {
+            console.log(this);
+        }
+    }
+    ",
+    "
+    function foo() {
+        var _this = this;
+        const bar = function() {
+            var _ref = _asyncToGenerator(function*(baz = _this.baz) {
+                console.log(_this);
+            });
+            return function bar() {
+                return _ref.apply(this, arguments);
+            };
+        }();
+    }
+    "
+);
+
 #[testing::fixture("tests/async-to-generator/**/exec.js")]
 fn exec(input: PathBuf) {
     let input = read_to_string(&input).unwrap();