fix `pure_getters` for chained property access (#1798)
authorAlex Lam S.L <alexlamsl@gmail.com>
Fri, 7 Apr 2017 09:06:01 +0000 (17:06 +0800)
committerGitHub <noreply@github.com>
Fri, 7 Apr 2017 09:06:01 +0000 (17:06 +0800)
lib/compress.js
test/compress/pure_getters.js

index b001d35..03b1fef 100644 (file)
@@ -1165,13 +1165,16 @@ merge(Compressor.prototype, {
     // may_eq_null()
     // returns true if this node may evaluate to null or undefined
     (function(def) {
-        function is_strict(compressor) {
-            return /strict/.test(compressor.option("pure_getters"));
+        AST_Node.DEFMETHOD("may_eq_null", function(compressor) {
+            var pure_getters = compressor.option("pure_getters");
+            return !pure_getters || this._eq_null(pure_getters);
+        });
+
+        function is_strict(pure_getters) {
+            return /strict/.test(pure_getters);
         }
 
-        def(AST_Node, function(compressor) {
-            return !is_strict(compressor);
-        });
+        def(AST_Node, is_strict);
         def(AST_Null, return_true);
         def(AST_Undefined, return_true);
         def(AST_Constant, return_false);
@@ -1182,36 +1185,36 @@ merge(Compressor.prototype, {
         def(AST_UnaryPrefix, function() {
             return this.operator == "void";
         });
-        def(AST_Binary, function(compressor) {
+        def(AST_Binary, function(pure_getters) {
             switch (this.operator) {
               case "&&":
-                return this.left.may_eq_null(compressor);
+                return this.left._eq_null(pure_getters);
               case "||":
-                return this.left.may_eq_null(compressor)
-                    && this.right.may_eq_null(compressor);
+                return this.left._eq_null(pure_getters)
+                    && this.right._eq_null(pure_getters);
               default:
                 return false;
             }
         })
-        def(AST_Assign, function(compressor) {
+        def(AST_Assign, function(pure_getters) {
             return this.operator == "="
-                && this.right.may_eq_null(compressor);
+                && this.right._eq_null(pure_getters);
         })
-        def(AST_Conditional, function(compressor) {
-            return this.consequent.may_eq_null(compressor)
-                || this.alternative.may_eq_null(compressor);
+        def(AST_Conditional, function(pure_getters) {
+            return this.consequent._eq_null(pure_getters)
+                || this.alternative._eq_null(pure_getters);
         })
-        def(AST_Seq, function(compressor) {
-            return this.cdr.may_eq_null(compressor);
+        def(AST_Seq, function(pure_getters) {
+            return this.cdr._eq_null(pure_getters);
         });
-        def(AST_SymbolRef, function(compressor) {
+        def(AST_SymbolRef, function(pure_getters) {
             if (this.is_undefined) return true;
-            if (!is_strict(compressor)) return false;
+            if (!is_strict(pure_getters)) return false;
             var fixed = this.fixed_value();
-            return !fixed || fixed.may_eq_null(compressor);
+            return !fixed || fixed._eq_null(pure_getters);
         });
     })(function(node, func) {
-        node.DEFMETHOD("may_eq_null", func);
+        node.DEFMETHOD("_eq_null", func);
     });
 
     /* -----[ boolean/negation helpers ]----- */
@@ -1754,12 +1757,10 @@ merge(Compressor.prototype, {
             return any(this.elements, compressor);
         });
         def(AST_Dot, function(compressor){
-            if (!compressor.option("pure_getters")) return true;
             return this.expression.may_eq_null(compressor)
                 || this.expression.has_side_effects(compressor);
         });
         def(AST_Sub, function(compressor){
-            if (!compressor.option("pure_getters")) return true;
             return this.expression.may_eq_null(compressor)
                 || this.expression.has_side_effects(compressor)
                 || this.property.has_side_effects(compressor);
@@ -2327,12 +2328,10 @@ merge(Compressor.prototype, {
             return values && AST_Seq.from_array(values);
         });
         def(AST_Dot, function(compressor, first_in_statement){
-            if (!compressor.option("pure_getters")) return this;
             if (this.expression.may_eq_null(compressor)) return this;
             return this.expression.drop_side_effect_free(compressor, first_in_statement);
         });
         def(AST_Sub, function(compressor, first_in_statement){
-            if (!compressor.option("pure_getters")) return this;
             if (this.expression.may_eq_null(compressor)) return this;
             var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
             if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
index c2dcb95..846b53c 100644 (file)
@@ -106,3 +106,16 @@ unsafe_reduce_vars: {
         (void 0).prop;
     }
 }
+
+chained: {
+    options = {
+        pure_getters: "strict",
+        side_effects: true,
+    }
+    input: {
+        a.b.c;
+    }
+    expect: {
+        a.b.c;
+    }
+}