fix corner case in `ie8` & `rename` (#3223)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 26 Jul 2018 08:35:43 +0000 (16:35 +0800)
committerGitHub <noreply@github.com>
Thu, 26 Jul 2018 08:35:43 +0000 (16:35 +0800)
lib/ast.js
lib/propmangle.js
lib/scope.js
test/compress/ie8.js
test/compress/rename.js

index b383dd0..09c29b4 100644 (file)
@@ -118,10 +118,8 @@ var AST_Node = DEFNODE("Node", "start end", {
     }
 }, null);
 
-AST_Node.warn_function = null;
 AST_Node.warn = function(txt, props) {
-    if (AST_Node.warn_function)
-        AST_Node.warn_function(string_template(txt, props));
+    if (AST_Node.warn_function) AST_Node.warn_function(string_template(txt, props));
 };
 
 /* -----[ statements ]----- */
@@ -207,8 +205,7 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
             var label = node.label;
             var def = this.label;
             node.walk(new TreeWalker(function(node) {
-                if (node instanceof AST_LoopControl
-                    && node.label && node.label.thedef === def) {
+                if (node instanceof AST_LoopControl && node.label && node.label.thedef === def) {
                     node.label.thedef = label;
                     label.references.push(node);
                 }
index 7ad4804..9f8bc7f 100644 (file)
@@ -53,25 +53,30 @@ function find_builtins(reserved) {
         "-Infinity",
         "undefined",
     ].forEach(add);
-    [ Object, Array, Function, Number,
-      String, Boolean, Error, Math,
-      Date, RegExp
+    [
+        Array,
+        Boolean,
+        Date,
+        Error,
+        Function,
+        Math,
+        Number,
+        Object,
+        RegExp,
+        String,
     ].forEach(function(ctor) {
         Object.getOwnPropertyNames(ctor).map(add);
         if (ctor.prototype) {
             Object.getOwnPropertyNames(ctor.prototype).map(add);
         }
     });
+
     function add(name) {
         push_uniq(reserved, name);
     }
 }
 
 function reserve_quoted_keys(ast, reserved) {
-    function add(name) {
-        push_uniq(reserved, name);
-    }
-
     ast.walk(new TreeWalker(function(node) {
         if (node instanceof AST_ObjectKeyVal && node.quote) {
             add(node.key);
@@ -79,6 +84,10 @@ function reserve_quoted_keys(ast, reserved) {
             addStrings(node.property, add);
         }
     }));
+
+    function add(name) {
+        push_uniq(reserved, name);
+    }
 }
 
 function addStrings(node, add) {
@@ -127,10 +136,8 @@ function mangle_properties(ast, options) {
     // note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
     // the same as passing an empty string.
     var debug = options.debug !== false;
-    var debug_name_suffix;
-    if (debug) {
-        debug_name_suffix = (options.debug === true ? "" : options.debug);
-    }
+    var debug_suffix;
+    if (debug) debug_suffix = options.debug === true ? "" : options.debug;
 
     var names_to_mangle = [];
     var unmangleable = [];
@@ -139,18 +146,14 @@ function mangle_properties(ast, options) {
     ast.walk(new TreeWalker(function(node) {
         if (node instanceof AST_ObjectKeyVal) {
             add(node.key);
-        }
-        else if (node instanceof AST_ObjectProperty) {
+        } else if (node instanceof AST_ObjectProperty) {
             // setter or getter, since KeyVal is handled above
             add(node.key.name);
-        }
-        else if (node instanceof AST_Dot) {
+        } else if (node instanceof AST_Dot) {
             add(node.property);
-        }
-        else if (node instanceof AST_Sub) {
+        } else if (node instanceof AST_Sub) {
             addStrings(node.property, add);
-        }
-        else if (node instanceof AST_Call
+        } else if (node instanceof AST_Call
             && node.expression.print_to_string() == "Object.defineProperty") {
             addStrings(node.args[1], add);
         }
@@ -160,18 +163,14 @@ function mangle_properties(ast, options) {
     return ast.transform(new TreeTransformer(function(node) {
         if (node instanceof AST_ObjectKeyVal) {
             node.key = mangle(node.key);
-        }
-        else if (node instanceof AST_ObjectProperty) {
+        } else if (node instanceof AST_ObjectProperty) {
             // setter or getter
             node.key.name = mangle(node.key.name);
-        }
-        else if (node instanceof AST_Dot) {
+        } else if (node instanceof AST_Dot) {
             node.property = mangle(node.property);
-        }
-        else if (!options.keep_quoted && node instanceof AST_Sub) {
+        } else if (!options.keep_quoted && node instanceof AST_Sub) {
             node.property = mangleStrings(node.property);
-        }
-        else if (node instanceof AST_Call
+        } else if (node instanceof AST_Call
             && node.expression.print_to_string() == "Object.defineProperty") {
             node.args[1] = mangleStrings(node.args[1]);
         }
@@ -182,9 +181,7 @@ function mangle_properties(ast, options) {
     function can_mangle(name) {
         if (unmangleable.indexOf(name) >= 0) return false;
         if (reserved.indexOf(name) >= 0) return false;
-        if (options.only_cache) {
-            return cache.has(name);
-        }
+        if (options.only_cache) return cache.has(name);
         if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
         return true;
     }
@@ -192,42 +189,29 @@ function mangle_properties(ast, options) {
     function should_mangle(name) {
         if (regex && !regex.test(name)) return false;
         if (reserved.indexOf(name) >= 0) return false;
-        return cache.has(name)
-            || names_to_mangle.indexOf(name) >= 0;
+        return cache.has(name) || names_to_mangle.indexOf(name) >= 0;
     }
 
     function add(name) {
-        if (can_mangle(name))
-            push_uniq(names_to_mangle, name);
-
-        if (!should_mangle(name)) {
-            push_uniq(unmangleable, name);
-        }
+        if (can_mangle(name)) push_uniq(names_to_mangle, name);
+        if (!should_mangle(name)) push_uniq(unmangleable, name);
     }
 
     function mangle(name) {
         if (!should_mangle(name)) {
             return name;
         }
-
         var mangled = cache.get(name);
         if (!mangled) {
             if (debug) {
                 // debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
-                var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
-
-                if (can_mangle(debug_mangled)) {
-                    mangled = debug_mangled;
-                }
+                var debug_mangled = "_$" + name + "$" + debug_suffix + "_";
+                if (can_mangle(debug_mangled)) mangled = debug_mangled;
             }
-
             // either debug mode is off, or it is on and we could not use the mangled name
-            if (!mangled) {
-                do {
-                    mangled = base54(++cname);
-                } while (!can_mangle(mangled));
-            }
-
+            if (!mangled) do {
+                mangled = base54(++cname);
+            } while (!can_mangle(mangled));
             cache.set(name, mangled);
         }
         return mangled;
@@ -238,11 +222,9 @@ function mangle_properties(ast, options) {
             if (node instanceof AST_Sequence) {
                 var last = node.expressions.length - 1;
                 node.expressions[last] = mangleStrings(node.expressions[last]);
-            }
-            else if (node instanceof AST_String) {
+            } else if (node instanceof AST_String) {
                 node.value = mangle(node.value);
-            }
-            else if (node instanceof AST_Conditional) {
+            } else if (node instanceof AST_Conditional) {
                 node.consequent = mangleStrings(node.consequent);
                 node.alternative = mangleStrings(node.alternative);
             }
index ab207d6..ac7df7d 100644 (file)
@@ -136,7 +136,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
             // AST_Defun node before getting to its AST_Symbol.
             (node.scope = defun.parent_scope.resolve()).def_function(node, defun);
         } else if (node instanceof AST_SymbolLambda) {
-            defun.def_function(node, node.name == "arguments" ? undefined : defun);
+            var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
+            if (options.ie8) def.defun = defun.parent_scope.resolve();
         } else if (node instanceof AST_SymbolVar) {
             defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
             if (defun !== scope) {
index c5a20ed..dd9bae4 100644 (file)
@@ -458,8 +458,8 @@ issue_2976_2: {
     }
     expect: {
         console.log(function f() {
-            var o;
-            return o === f ? "FAIL" : "PASS";
+            var n;
+            return n === f ? "FAIL" : "PASS";
         }());
     }
     expect_stdout: "PASS"
@@ -477,9 +477,9 @@ issue_2976_3: {
         }());
     }
     expect: {
-        console.log(function r() {
-            var o;
-            return o === r ? "FAIL" : "PASS";
+        console.log(function o() {
+            var n;
+            return n === o ? "FAIL" : "PASS";
         }());
     }
     expect_stdout: "PASS"
@@ -772,17 +772,17 @@ issue_3215_2: {
     }
     expect: {
         console.log(function foo() {
-            var r = function r(o) {
+            var o = function o(n) {
                 return "PASS";
             };
             try {
                 "moo";
-            } catch (o) {
-                r = function r(o) {
+            } catch (n) {
+                o = function o(n) {
                     return "FAIL";
                 };
             }
-            return r;
+            return o;
         }()());
     }
     expect_stdout: "PASS"
@@ -846,17 +846,17 @@ issue_3215_4: {
     }
     expect: {
         console.log(function foo() {
-            var r = function r(o) {
+            var o = function o(n) {
                 return "FAIL";
             };
             try {
                 moo;
-            } catch (o) {
-                r = function r(o) {
+            } catch (n) {
+                o = function o(n) {
                     return "PASS";
                 };
             }
-            return r;
+            return o;
         }()());
     }
     expect_stdout: "PASS"
index 83187df..eab989b 100644 (file)
@@ -534,3 +534,80 @@ function_catch_catch_ie8: {
         "undefined",
     ]
 }
+
+function_do_catch_ie8: {
+    rename = true
+    options = {
+        ie8: true,
+        side_effects: true,
+        unused: true,
+    }
+    mangle = {
+        ie8: true,
+        toplevel: true,
+    }
+    input: {
+        var a = 1, b = 1, c = 0;
+        function d(e) {
+            var f, g, h, i;
+            do {
+                try {
+                    try {
+                        var j = function q(){}();
+                    } catch (r) {
+                        --a && w("ddddddddeeeeeeegggggggggiiiiilllllllnnnnntuuuuuuuuyyyyyyy");
+                        var k, l, m, n, o;
+                        --m;
+                        --n;
+                        --o;
+                    }
+                    try {
+                        i[1];
+                    } catch (s) {
+                        var p;
+                        switch (function t() {
+                            c++;
+                        }()) {
+                          case j + --p:
+                        }
+                    }
+                } catch (u) {}
+            } while (--i);
+            b--;
+        }
+        d();
+        console.log(b, c);
+    }
+    expect: {
+        var t = 1, u = 1, y = 0;
+        function c(c) {
+            var d;
+            do {
+                try {
+                    try {
+                        var e = void 0;
+                    } catch (i) {
+                        --t && w("ddddddddeeeeeeegggggggggiiiiilllllllnnnnntuuuuuuuuyyyyyyy");
+                        0;
+                        0;
+                        0;
+                    }
+                    try {
+                        d[1];
+                    } catch (l) {
+                        var g;
+                        switch(function x() {
+                            y++;
+                        }()) {
+                          case e + --g:
+                        }
+                    }
+                } catch (n) {}
+            } while (--d);
+            u--;
+        }
+        c();
+        console.log(u, y);
+    }
+    expect_stdout: "0 1"
+}