fix `unsafe` escape analysis in `reduce_vars` (#2387)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 21 Oct 2017 19:23:31 +0000 (03:23 +0800)
committerGitHub <noreply@github.com>
Sat, 21 Oct 2017 19:23:31 +0000 (03:23 +0800)
lib/compress.js
test/compress/arrays.js
test/compress/functions.js
test/compress/reduce_vars.js

index 1f58b39..c7e0863 100644 (file)
@@ -327,13 +327,7 @@ merge(Compressor.prototype, {
                                 d.fixed = false;
                             }
                         } else {
-                            var parent = tw.parent();
-                            if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
-                                || parent instanceof AST_Call && node !== parent.expression
-                                || parent instanceof AST_Return && node === parent.value && node.scope !== d.scope
-                                || parent instanceof AST_VarDef && node === parent.value) {
-                                d.escaped = true;
-                            }
+                            mark_escaped(d, node, 0);
                         }
                     }
                 }
@@ -579,6 +573,18 @@ merge(Compressor.prototype, {
                 return !immutable && is_modified(parent, level + 1);
             }
         }
+
+        function mark_escaped(d, node, level) {
+            var parent = tw.parent(level);
+            if (parent instanceof AST_Assign && parent.operator == "=" && node === parent.right
+                || parent instanceof AST_Call && node !== parent.expression
+                || parent instanceof AST_Return && node === parent.value && node.scope !== d.scope
+                || parent instanceof AST_VarDef && node === parent.value) {
+                d.escaped = true;
+            } else if (parent instanceof AST_PropAccess && node === parent.expression) {
+                mark_escaped(d, parent, level + 1);
+            }
+        }
     });
 
     AST_SymbolRef.DEFMETHOD("fixed_value", function() {
index f0ded06..539dfb0 100644 (file)
@@ -128,50 +128,55 @@ constant_join_3: {
 
 for_loop: {
     options = {
-        unsafe      : true,
-        unused      : true,
-        evaluate    : true,
-        reduce_vars : true
+        evaluate: true,
+        reduce_vars: true,
+        unsafe: true,
     };
     input: {
         function f0() {
             var a = [1, 2, 3];
-            for (var i = 0; i < a.length; i++) {
-                console.log(a[i]);
-            }
+            var b = 0;
+            for (var i = 0; i < a.length; i++)
+                b += a[i];
+            return b;
         }
-
         function f1() {
             var a = [1, 2, 3];
-            for (var i = 0, len = a.length; i < len; i++) {
-                console.log(a[i]);
-            }
+            var b = 0;
+            for (var i = 0, len = a.length; i < len; i++)
+                b += a[i];
+            return b;
         }
-
         function f2() {
             var a = [1, 2, 3];
-            for (var i = 0; i < a.length; i++) {
+            for (var i = 0; i < a.length; i++)
                 a[i]++;
-            }
+            return a[2];
         }
+        console.log(f0(), f1(), f2());
     }
     expect: {
         function f0() {
             var a = [1, 2, 3];
+            var b = 0;
             for (var i = 0; i < 3; i++)
-                console.log(a[i]);
+                b += a[i];
+            return b;
         }
-
         function f1() {
             var a = [1, 2, 3];
-            for (var i = 0; i < 3; i++)
-                console.log(a[i]);
+            var b = 0;
+            for (var i = 0, len = a.length; i < len; i++)
+                b += a[i];
+            return b;
         }
-
         function f2() {
             var a = [1, 2, 3];
             for (var i = 0; i < a.length; i++)
                 a[i]++;
+            return a[2];
         }
+        console.log(f0(), f1(), f2());
     }
+    expect_stdout: "6 6 4"
 }
index f411afa..6c82557 100644 (file)
@@ -151,13 +151,13 @@ issue_1841_2: {
 
 function_returning_constant_literal: {
     options = {
+        inline: true,
+        passes: 2,
         reduce_vars: true,
-        unsafe: true,
+        side_effects: true,
         toplevel: true,
-        evaluate: true,
-        cascade: true,
+        unsafe: true,
         unused: true,
-        inline: true,
     }
     input: {
         function greeter() {
index a03bc1c..681dafd 100644 (file)
@@ -2954,3 +2954,32 @@ const_expr_2: {
     }
     expect_stdout: "2 2"
 }
+
+escaped_prop: {
+    options = {
+        collapse_vars: true,
+        evaluate: true,
+        inline: true,
+        pure_getters: "strict",
+        reduce_vars: true,
+        side_effects: true,
+        toplevel: true,
+        unsafe: true,
+        unused: true,
+    }
+    input: {
+        var obj = { o: { a: 1 } };
+        (function(o) {
+            o.a++;
+        })(obj.o);
+        (function(o) {
+            console.log(o.a);
+        })(obj.o);
+    }
+    expect: {
+        var obj = { o: { a: 1 } };
+        obj.o.a++;
+        console.log(obj.o.a);
+    }
+    expect_stdout: "2"
+}