Repository: swc-project/swc (rust)

Issue:
minify hoist_fns bug
### Describe the bug

should log `true`, but TypeError

### Input code

```typescript
(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Sentry = {}));
})(this, (function (exports) { 'use strict';
  function isGlobalObj(obj) {
    return obj && obj.Math == Math ? obj : undefined;
  }
  const GLOBAL_OBJ =
    (typeof globalThis == 'object' && isGlobalObj(globalThis)) ||
    // eslint-disable-next-line no-restricted-globals
    (isGlobalObj(globalThis)) ||
    (typeof self == 'object' && isGlobalObj(self)) ||
    (typeof global == 'object' && isGlobalObj(global)) ||
    (function () {
      return this;
    })() ||
    {};
  function getGlobalObject() {
    return GLOBAL_OBJ ;
  }
  const WINDOW$6 = getGlobalObject();
  function supportsFetch() {
    if (!('fetch' in WINDOW$6)) {
      return false;
    }
    return true;
  }

  console.log(supportsFetch());
}));
```


### Config

```json
{
  "jsc": {
    "parser": {
      "syntax": "typescript",
      "tsx": false,
      "decorators": true
    },
    "target": "es2022",
    "loose": false,
    "minify": {
      "compress": {
        "hoist_funs": true
      },
      "mangle": false
    },
    "transform": {
      "decoratorVersion": "2022-03",
      "decoratorMetadata": true
    }
  },
  "module": {
    "type": "es6"
  },
  "minify": true,
  "isModule": true
}
```


### Playground link (or link to the minimal reproduction)

https://play.swc.rs/?version=1.3.94-nightly-20231016.1&code=H4sIAAAAAAAAA4WSUUvDMBDH3%2F0UJ8iagt3efNgo4hCHou5BwQcR6drrlpElo0nBMffdvSRt1m2iD21ILve7%2F%2F0vrKxlbriSwOZCzTJxCWWWG1VtYtieAZjNGlUJ%2BLVWldGQpilEarbE3ETQ67XhlSpqgXBuo7UssOQSiwiuWxZr8mMY7pn%2Bmke2KhzUB%2FrZqiCC37D3qEFEHx2FltbohrTl%2Bv3rgutfBHWCw2YD39%2BgUZSB2xD7LyhNtSHwdhfHo7NdzAzlXQLbexb62lIdjaBNxcmaEekKl7ieON50tmRknfcVoEJTVxLoxPZMS%2F8pMwuyA9x67SJDCOotc0dfrqQ2MHmcjm8eP6fjB0gdjp12fzSrro79rTim%2Fh1hMADUgkuTFFxnM4GJxC%2BTCDskqZIKfXNYJD5b%2B7r%2FYVth1uK%2FJNn4aVY73P9a6WTup9NaHcy28xu5IxpmyNjuDuY1RxPoVJAdDazj%2FOFI3u6fb6dvF1f0YE4QBwV0vXav5g5Nvgh4XgI7Z1FpDyPgMvDikzZKMh%2BbPrrSTFWj19SIUgL7Qs3ZUUX3mOn3A7g%2F9jT9AwAA&config=H4sIAAAAAAAAA2VQSwrCQAzde4qStYJUcOEd3LqV0KZ1pJ2UJAWLeHdn%2Bhlb3E3ey7xP3rssg6cWcMne4RmGDkVJ0hwQHbzhKyBgQ0daiOsM9gtrGqkKG6WElVSwoLFooEx6GonPxIOh1GRRjzQ%2F5vmsBQ2z0lYLWuddNazTFNx2QqorLKAPdmr3qvcbx%2BQZldDXTZLfBhL0WrG0a5%2FU4Uaijn3MG9Mejif4L3olwxINN313swW0XPaj93zjeMep%2Fxl%2BS0vVKDAiTq%2FLx1H08wWMaKbbrgEAAA%3D%3D

### SWC Info output

_No response_

### Expected behavior

log `true`

### Actual behavior

TypeError

### Version

1.3.94-nightly-20231016.1

### Additional context

_No response_

Pull request description:
fix(es/minifier): Make `Finalizer` inline literals
**Related issue:**

 - Closes #8284 

Patch:
diff --git a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs
index 9875d38754..e012773113 100644
--- a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs
+++ b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs
@@ -267,6 +267,7 @@ impl Vars {
     {
         let mut changed = false;
         if !self.simple_functions.is_empty()
+            || !self.lits.is_empty()
             || !self.lits_for_cmp.is_empty()
             || !self.lits_for_array_access.is_empty()
             || !self.removed.is_empty()
@@ -275,6 +276,7 @@ impl Vars {
                 simple_functions: &self.simple_functions,
                 lits_for_cmp: &self.lits_for_cmp,
                 lits_for_array_access: &self.lits_for_array_access,
+                lits: &self.lits,
                 vars_to_remove: &self.removed,
                 changed: false,
             };
diff --git a/crates/swc_ecma_minifier/src/compress/optimize/util.rs b/crates/swc_ecma_minifier/src/compress/optimize/util.rs
index cd6e7f1715..ac096bff6e 100644
--- a/crates/swc_ecma_minifier/src/compress/optimize/util.rs
+++ b/crates/swc_ecma_minifier/src/compress/optimize/util.rs
@@ -221,6 +221,7 @@ pub(crate) fn is_valid_for_lhs(e: &Expr) -> bool {
 #[derive(Clone, Copy)]
 pub(crate) struct Finalizer<'a> {
     pub simple_functions: &'a FxHashMap<Id, Box<Expr>>,
+    pub lits: &'a FxHashMap<Id, Box<Expr>>,
     pub lits_for_cmp: &'a FxHashMap<Id, Box<Expr>>,
     pub lits_for_array_access: &'a FxHashMap<Id, Box<Expr>>,
 
@@ -378,6 +379,16 @@ impl VisitMut for Finalizer<'_> {
         });
     }
 
+    fn visit_mut_expr(&mut self, n: &mut Expr) {
+        if let Expr::Ident(i) = n {
+            if let Some(expr) = self.lits.get(&i.to_id()) {
+                *n = *expr.clone();
+            }
+        } else {
+            n.visit_mut_children_with(self);
+        }
+    }
+
     fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
         self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
             n.visit_mut_with(v);


Test patch:
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8284/config.json b/crates/swc_ecma_minifier/tests/fixture/issues/8284/config.json
new file mode 100644
index 0000000000..41c9a28d82
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/8284/config.json
@@ -0,0 +1,6 @@
+{
+    "hoist_funs": true,
+    "defaults": true,
+    "toplevel": true,
+    "passes": 0
+}
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8284/input.js b/crates/swc_ecma_minifier/tests/fixture/issues/8284/input.js
new file mode 100644
index 0000000000..847027a7f8
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/8284/input.js
@@ -0,0 +1,36 @@
+(function (global, factory) {
+    typeof exports === "object" && typeof module !== "undefined"
+        ? factory(exports)
+        : typeof define === "function" && define.amd
+        ? define(["exports"], factory)
+        : ((global =
+              typeof globalThis !== "undefined" ? globalThis : global || self),
+          factory((global.Sentry = {})));
+})(this, function (exports) {
+    "use strict";
+    function isGlobalObj(obj) {
+        return obj && obj.Math == Math ? obj : undefined;
+    }
+    const GLOBAL_OBJ =
+        (typeof globalThis == "object" && isGlobalObj(globalThis)) ||
+        // eslint-disable-next-line no-restricted-globals
+        isGlobalObj(globalThis) ||
+        (typeof self == "object" && isGlobalObj(self)) ||
+        (typeof global == "object" && isGlobalObj(global)) ||
+        (function () {
+            return this;
+        })() ||
+        {};
+    function getGlobalObject() {
+        return GLOBAL_OBJ;
+    }
+    const WINDOW$6 = getGlobalObject();
+    function supportsFetch() {
+        if (!("fetch" in WINDOW$6)) {
+            return false;
+        }
+        return true;
+    }
+
+    console.log(supportsFetch());
+});
diff --git a/crates/swc_ecma_minifier/tests/fixture/issues/8284/output.js b/crates/swc_ecma_minifier/tests/fixture/issues/8284/output.js
new file mode 100644
index 0000000000..bb8cc09767
--- /dev/null
+++ b/crates/swc_ecma_minifier/tests/fixture/issues/8284/output.js
@@ -0,0 +1,12 @@
+var global1, factory;
+global1 = this, factory = function(exports1) {
+    function isGlobalObj(obj) {
+        return obj && obj.Math == Math ? obj : void 0;
+    }
+    "use strict";
+    console.log("fetch" in ("object" == typeof globalThis && isGlobalObj(globalThis) || isGlobalObj(globalThis) || "object" == typeof self && isGlobalObj(self) || "object" == typeof global && isGlobalObj(global) || function() {
+        return this;
+    }() || {}));
+}, "object" == typeof exports && "undefined" != typeof module ? factory(exports) : "function" == typeof define && define.amd ? define([
+    "exports"
+], factory) : factory((global1 = "undefined" != typeof globalThis ? globalThis : global1 || self).Sentry = {});