fix corner case in `mangle` (#4311)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 21 Nov 2020 00:05:40 +0000 (00:05 +0000)
committerGitHub <noreply@github.com>
Sat, 21 Nov 2020 00:05:40 +0000 (08:05 +0800)
lib/scope.js
test/compress/const.js

index 0e44280..4cc65c7 100644 (file)
@@ -72,7 +72,7 @@ SymbolDef.prototype = {
             if (def) {
                 this.mangled_name = def.mangled_name || def.name;
             } else {
-                this.mangled_name = next_mangled_name(this.scope, options, this);
+                this.mangled_name = next_mangled_name(this, options);
             }
             if (this.global && cache) {
                 cache.set(this.name, this.mangled_name);
@@ -432,7 +432,8 @@ function names_in_use(scope, options) {
     return names;
 }
 
-function next_mangled_name(scope, options, def) {
+function next_mangled_name(def, options) {
+    var scope = def.scope;
     var in_use = names_in_use(scope, options);
     var holes = scope.cname_holes;
     var names = Object.create(null);
@@ -519,9 +520,9 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
             return true;
         }
         if (node instanceof AST_BlockScope) {
-            var to_mangle = [];
+            node.to_mangle = [];
             node.variables.each(function(def) {
-                if (!defer_redef(def)) to_mangle.push(def);
+                if (!defer_redef(def)) node.to_mangle.push(def);
             });
             descend();
             if (options.cache && node instanceof AST_Toplevel) {
@@ -532,7 +533,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
                 sym.scope = node;
                 sym.reference(options);
             }
-            to_mangle.forEach(mangle);
+            node.to_mangle.forEach(mangle);
             return true;
         }
         if (node instanceof AST_Label) {
@@ -552,13 +553,19 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
         def.mangle(options);
     }
 
-    function defer_redef(def, node) {
+    function defer_redef(def) {
+        var sym = def.orig[0];
         var redef = def.redefined();
-        if (!redef) return false;
+        if (!redef) {
+            if (!(sym instanceof AST_SymbolConst)) return false;
+            var scope = def.scope.resolve();
+            if (def.scope === scope) return false;
+            redef = scope.def_variable(sym);
+            scope.to_mangle.push(redef);
+        }
         redefined.push(def);
         def.references.forEach(reference);
-        var node = def.orig[0];
-        if (node instanceof AST_SymbolCatch || node instanceof AST_SymbolConst) reference(node);
+        if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) reference(sym);
         return true;
 
         function reference(sym) {
index 8dbe74d..c269f8c 100644 (file)
@@ -1,3 +1,45 @@
+mangle_block: {
+    mangle = {
+        toplevel: false,
+    }
+    input: {
+        var o = "PASS";
+        {
+            const a = "FAIL";
+        }
+        console.log(o);
+    }
+    expect: {
+        var o = "PASS";
+        {
+            const a = "FAIL";
+        }
+        console.log(o);
+    }
+    expect_stdout: "PASS"
+}
+
+mangle_block_toplevel: {
+    mangle = {
+        toplevel: true,
+    }
+    input: {
+        var o = "PASS";
+        {
+            const a = "FAIL";
+        }
+        console.log(o);
+    }
+    expect: {
+        var o = "PASS";
+        {
+            const c = "FAIL";
+        }
+        console.log(o);
+    }
+    expect_stdout: "PASS"
+}
+
 mangle_catch_1: {
     mangle = {}
     input: {
@@ -11,8 +53,8 @@ mangle_catch_1: {
     expect: {
         try {
             throw "eeeee";
-        } catch (e) {
-            const o = typeof d;
+        } catch (o) {
+            const e = typeof d;
         }
         console.log(typeof a, typeof b);
     }