fix corner case in `reduce_vars` (#4211)
authorAlex Lam S.L <alexlamsl@gmail.com>
Tue, 13 Oct 2020 07:52:03 +0000 (08:52 +0100)
committerGitHub <noreply@github.com>
Tue, 13 Oct 2020 07:52:03 +0000 (15:52 +0800)
fixes #4210

lib/compress.js
lib/scope.js
test/compress/const.js

index 2307abc..e36fcaa 100644 (file)
@@ -6651,7 +6651,7 @@ merge(Compressor.prototype, {
             var s = def.scope;
             do {
                 s = s.parent_scope;
-                if (s.variables.has(node.name)) return false;
+                if (s.var_names()[node.name]) return false;
             } while (s !== scope);
             return true;
         }) ? make_node(AST_Var, self, {
index abb50c4..ef19a53 100644 (file)
@@ -82,10 +82,13 @@ SymbolDef.prototype = {
     redefined: function() {
         var scope = this.defun;
         if (!scope) return;
-        var def = scope.variables.get(this.name);
-        if (!def && scope instanceof AST_Toplevel) def = scope.globals.get(this.name);
-        if (!def || def === this) return;
-        return def.redefined() || def;
+        var name = this.name;
+        var def = scope.variables.get(name)
+            || scope instanceof AST_Toplevel && scope.globals.get(name)
+            || this.orig[0] instanceof AST_SymbolConst && find_if(function(def) {
+                return def.name == name;
+            }, scope.enclosed);
+        if (def && def !== this) return def.redefined() || def;
     },
     unmangleable: function(options) {
         return this.global && !options.toplevel
index aedfdbc..b161e87 100644 (file)
@@ -930,3 +930,36 @@ issue_4207: {
     }
     expect_stdout: "0"
 }
+
+issue_4210: {
+    options = {
+        reduce_vars: true,
+    }
+    input: {
+        (function() {
+            try {
+                throw 42;
+            } catch (e) {
+                const a = typeof e;
+                console.log(a);
+            } finally {
+                return a = "foo";
+            }
+        })();
+        console.log(typeof a);
+    }
+    expect: {
+        (function() {
+            try {
+                throw 42;
+            } catch (e) {
+                const a = typeof e;
+                console.log(a);
+            } finally {
+                return a = "foo";
+            }
+        })();
+        console.log(typeof a);
+    }
+    expect_stdout: true
+}