improve fix for #3958 (#3960)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 6 Jun 2020 14:07:32 +0000 (15:07 +0100)
committerGitHub <noreply@github.com>
Sat, 6 Jun 2020 14:07:32 +0000 (15:07 +0100)
lib/compress.js

index f71d956..6aa81a5 100644 (file)
@@ -352,23 +352,6 @@ merge(Compressor.prototype, {
         return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg;
     }
 
-    function is_content_constant(ref, depth) {
-        var escaped = ref.definition().escaped;
-        switch (escaped.length) {
-          case 0:
-            return true;
-          case 1:
-            var found = false;
-            escaped[0].walk(new TreeWalker(function(node) {
-                if (found) return true;
-                if (node === ref) return found = true;
-            }));
-            return found;
-          default:
-            return depth <= escaped.depth;
-        }
-    }
-
     (function(def) {
         def(AST_Node, noop);
 
@@ -512,16 +495,10 @@ merge(Compressor.prototype, {
             });
         }
 
-        function to_value(def, sym, fixed) {
-            if (fixed == null) {
-                fixed = make_node(AST_Undefined, sym);
-            } else if (typeof fixed == "function") {
-                fixed = fixed();
-            }
-            if (fixed instanceof AST_Array || fixed instanceof AST_Object) {
-                if (!is_content_constant(sym)) return false;
-            }
-            return fixed;
+        function make_ref(ref, fixed) {
+            var node = make_node(AST_SymbolRef, ref, ref);
+            node.fixed = fixed || make_node(AST_Undefined, ref);
+            return node;
         }
 
         function ref_once(compressor, def) {
@@ -618,10 +595,9 @@ merge(Compressor.prototype, {
                     };
                 } else {
                     sym.fixed = d.fixed = function() {
-                        var value = to_value(d, sym, fixed);
-                        return value && make_node(AST_Binary, node, {
+                        return make_node(AST_Binary, node, {
                             operator: node.operator.slice(0, -1),
-                            left: value,
+                            left: make_ref(sym, fixed),
                             right: node.right
                         });
                     };
@@ -900,12 +876,11 @@ merge(Compressor.prototype, {
                 push_ref(d, exp);
                 mark(tw, d);
                 d.fixed = function() {
-                    var value = to_value(d, exp, fixed);
-                    return value && make_node(AST_Binary, node, {
+                    return make_node(AST_Binary, node, {
                         operator: node.operator.slice(0, -1),
                         left: make_node(AST_UnaryPrefix, node, {
                             operator: "+",
-                            expression: value
+                            expression: make_ref(exp, fixed)
                         }),
                         right: make_node(AST_Number, node, {
                             value: 1
@@ -918,10 +893,9 @@ merge(Compressor.prototype, {
                     exp.fixed = d.fixed;
                 } else {
                     exp.fixed = function() {
-                        var value = to_value(d, exp, fixed);
-                        return value && make_node(AST_UnaryPrefix, node, {
+                        return make_node(AST_UnaryPrefix, node, {
                             operator: "+",
-                            expression: value
+                            expression: make_ref(exp, fixed)
                         });
                     };
                     exp.fixed.assigns = fixed && fixed.assigns;
@@ -3416,7 +3390,8 @@ merge(Compressor.prototype, {
                         && e.fixed_value() instanceof AST_Lambda)) {
                 return typeof function(){};
             }
-            if (!non_converting_unary[op]) depth++;
+            var def = e instanceof AST_SymbolRef && e.definition();
+            if (!non_converting_unary[op] && !(def && def.fixed)) depth++;
             var v = e._eval(compressor, ignore_side_effects, cached, depth);
             if (v === e) {
                 if (ignore_side_effects && op == "void") return;
@@ -3435,9 +3410,8 @@ merge(Compressor.prototype, {
               case "+": return +v;
               case "++":
               case "--":
-                if (!(e instanceof AST_SymbolRef)) return this;
+                if (!def) return this;
                 if (!ignore_side_effects) {
-                    var def = e.definition();
                     if (def.undeclared) return this;
                     if (def.last_ref !== e) return this;
                 }
@@ -3460,7 +3434,8 @@ merge(Compressor.prototype, {
                     if (def.last_ref !== e) return this;
                 }
             }
-            var v = e._eval(compressor, ignore_side_effects, cached, depth + 1);
+            if (!(e instanceof AST_SymbolRef && e.definition().fixed)) depth++;
+            var v = e._eval(compressor, ignore_side_effects, cached, depth);
             if (v === e) return this;
             modified(e);
             return +v;
@@ -3522,6 +3497,22 @@ merge(Compressor.prototype, {
             var value = node._eval(compressor, ignore_side_effects, cached, depth);
             return value === node ? this : value;
         });
+        function verify_escaped(ref, depth) {
+            var escaped = ref.definition().escaped;
+            switch (escaped.length) {
+              case 0:
+                return true;
+              case 1:
+                var found = false;
+                escaped[0].walk(new TreeWalker(function(node) {
+                    if (found) return true;
+                    if (node === ref) return found = true;
+                }));
+                return found;
+              default:
+                return depth <= escaped.depth;
+            }
+        }
         def(AST_SymbolRef, function(compressor, ignore_side_effects, cached, depth) {
             var fixed = this.fixed_value();
             if (!fixed) return this;
@@ -3538,8 +3529,7 @@ merge(Compressor.prototype, {
                 };
                 cached.push(fixed);
             }
-            if (value && typeof value == "object" && !is_content_constant(this, depth)) return this;
-            return value;
+            return value && typeof value == "object" && !verify_escaped(this, depth) ? this : value;
         });
         var global_objs = {
             Array: Array,