[Pkg-javascript-commits] [uglifyjs] 253/491: enhance `properties` (#2412)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:41 UTC 2018


This is an automated email from the git hooks/post-receive script.

js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.

commit 8428326ea120dece51b70d7bba63dda8eda14fd6
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Sun Oct 29 04:11:26 2017 +0800

    enhance `properties` (#2412)
    
    - trim array items only if `side_effects`
    - extend to non-identifier properties
---
 lib/compress.js              | 151 ++++++++++++++++++++++++-------------------
 test/compress/evaluate.js    |   2 +
 test/compress/properties.js  |  51 ++++++++++-----
 test/compress/reduce_vars.js |   1 +
 4 files changed, 124 insertions(+), 81 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 4817ec5..a1db985 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4537,59 +4537,72 @@ merge(Compressor.prototype, {
     });
 
     OPT(AST_Sub, function(self, compressor){
+        var expr = self.expression;
+        var prop = self.property;
         if (compressor.option("properties")) {
-            var prop = self.property;
-            if (prop instanceof AST_String) {
-                prop = prop.getValue();
-                if (is_identifier_string(prop)) {
+            var key = prop.evaluate(compressor);
+            if (key !== prop) {
+                var property = "" + key;
+                if (is_identifier_string(property)
+                    && property.length <= prop.print_to_string().length + 1) {
                     return make_node(AST_Dot, self, {
-                        expression : self.expression,
-                        property   : prop
+                        expression: expr,
+                        property: property
                     }).optimize(compressor);
                 }
-                var v = parseFloat(prop);
-                if (!isNaN(v) && v.toString() == prop) {
-                    self.property = make_node(AST_Number, self.property, {
-                        value: v
-                    });
+                if (!(prop instanceof AST_Number)) {
+                    var value = parseFloat(property);
+                    if (value.toString() == property) {
+                        prop = self.property = make_node(AST_Number, prop, {
+                            value: value
+                        });
+                    }
                 }
             }
-            if (prop instanceof AST_Number && self.expression instanceof AST_Array) {
-                prop = prop.getValue();
-                var elements = self.expression.elements;
-                if (prop in elements) {
-                    var flatten = true;
-                    var values = [];
-                    for (var i = elements.length; --i > prop;) {
-                        var value = elements[i].drop_side_effect_free(compressor);
-                        if (value) {
-                            values.unshift(value);
-                            if (flatten && value.has_side_effects(compressor)) flatten = false;
-                        }
-                    }
-                    var retValue = elements[prop];
-                    retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
-                    if (!flatten) values.unshift(retValue);
-                    while (--i >= 0) {
-                        var value = elements[i].drop_side_effect_free(compressor);
-                        if (value) values.unshift(value);
-                        else prop--;
+        }
+        if (is_lhs(self, compressor.parent())) return self;
+        if (compressor.option("properties") && key !== prop) {
+            var node = self.flatten_object(property);
+            if (node) {
+                expr = self.expression = node.expression;
+                prop = self.property = node.property;
+            }
+        }
+        if (compressor.option("properties") && compressor.option("side_effects")
+            && prop instanceof AST_Number && expr instanceof AST_Array) {
+            var index = prop.getValue();
+            var elements = expr.elements;
+            if (index in elements) {
+                var flatten = true;
+                var values = [];
+                for (var i = elements.length; --i > index;) {
+                    var value = elements[i].drop_side_effect_free(compressor);
+                    if (value) {
+                        values.unshift(value);
+                        if (flatten && value.has_side_effects(compressor)) flatten = false;
                     }
-                    if (flatten) {
-                        values.push(retValue);
-                        return make_sequence(self, values).optimize(compressor);
-                    } else return make_node(AST_Sub, self, {
-                        expression: make_node(AST_Array, self.expression, {
-                            elements: values
-                        }),
-                        property: make_node(AST_Number, self.property, {
-                            value: prop
-                        })
-                    });
                 }
+                var retValue = elements[index];
+                retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
+                if (!flatten) values.unshift(retValue);
+                while (--i >= 0) {
+                    var value = elements[i].drop_side_effect_free(compressor);
+                    if (value) values.unshift(value);
+                    else index--;
+                }
+                if (flatten) {
+                    values.push(retValue);
+                    return make_sequence(self, values).optimize(compressor);
+                } else return make_node(AST_Sub, self, {
+                    expression: make_node(AST_Array, expr, {
+                        elements: values
+                    }),
+                    property: make_node(AST_Number, prop, {
+                        value: index
+                    })
+                });
             }
         }
-        if (is_lhs(self, compressor.parent())) return self;
         var ev = self.evaluate(compressor);
         if (ev !== self) {
             ev = make_node_from_constant(ev, self).optimize(compressor);
@@ -4609,6 +4622,33 @@ merge(Compressor.prototype, {
         return result;
     });
 
+    AST_PropAccess.DEFMETHOD("flatten_object", function(key) {
+        var expr = this.expression;
+        if (expr instanceof AST_Object) {
+            var props = expr.properties;
+            for (var i = props.length; --i >= 0;) {
+                var prop = props[i];
+                if ("" + prop.key == key) {
+                    if (!all(props, function(prop) {
+                        return prop instanceof AST_ObjectKeyVal;
+                    })) break;
+                    var value = prop.value;
+                    if (value instanceof AST_Function && value.contains_this()) break;
+                    return make_node(AST_Sub, this, {
+                        expression: make_node(AST_Array, expr, {
+                            elements: props.map(function(prop) {
+                                return prop.value;
+                            })
+                        }),
+                        property: make_node(AST_Number, this, {
+                            value: i
+                        })
+                    });
+                }
+            }
+        }
+    });
+
     OPT(AST_Dot, function(self, compressor){
         var def = self.resolve_defines(compressor);
         if (def) {
@@ -4637,28 +4677,9 @@ merge(Compressor.prototype, {
             }
         }
         if (is_lhs(self, compressor.parent())) return self;
-        if (compressor.option("properties") && self.expression instanceof AST_Object) {
-            var props = self.expression.properties;
-            for (var i = props.length; --i >= 0;) {
-                var prop = props[i];
-                if (prop.key === self.property) {
-                    if (!all(props, function(prop) {
-                        return prop instanceof AST_ObjectKeyVal;
-                    })) break;
-                    var value = prop.value;
-                    if (value instanceof AST_Function && value.contains_this()) break;
-                    return make_node(AST_Sub, self, {
-                        expression: make_node(AST_Array, self.expression, {
-                            elements: props.map(function(prop) {
-                                return prop.value;
-                            })
-                        }),
-                        property: make_node(AST_Number, self, {
-                            value: i
-                        })
-                    }).optimize(compressor);
-                }
-            }
+        if (compressor.option("properties")) {
+            var node = self.flatten_object(self.property);
+            if (node) return node.optimize(compressor);
         }
         var ev = self.evaluate(compressor);
         if (ev !== self) {
diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js
index dc8ceb6..64728c0 100644
--- a/test/compress/evaluate.js
+++ b/test/compress/evaluate.js
@@ -390,6 +390,7 @@ prop_function: {
     options = {
         evaluate: true,
         properties: true,
+        side_effects: true,
     }
     input: {
         console.log(
@@ -634,6 +635,7 @@ prototype_function: {
     options = {
         evaluate: true,
         properties: true,
+        side_effects: true,
     }
     input: {
         var a = ({valueOf: 0}) < 1;
diff --git a/test/compress/properties.js b/test/compress/properties.js
index f435d37..1b5e7fc 100644
--- a/test/compress/properties.js
+++ b/test/compress/properties.js
@@ -1,7 +1,8 @@
 keep_properties: {
     options = {
-        properties: false
-    };
+        evaluate: true,
+        properties: false,
+    }
     input: {
         a["foo"] = "bar";
     }
@@ -12,6 +13,7 @@ keep_properties: {
 
 dot_properties: {
     options = {
+        evaluate: true,
         properties: true,
     }
     beautify = {
@@ -37,6 +39,7 @@ dot_properties: {
 
 dot_properties_es5: {
     options = {
+        evaluate: true,
         properties: true,
     }
     beautify = {
@@ -61,8 +64,8 @@ dot_properties_es5: {
 sub_properties: {
     options = {
         evaluate: true,
-        properties: true
-    };
+        properties: true,
+    }
     input: {
         a[0] = 0;
         a["0"] = 1;
@@ -81,18 +84,18 @@ sub_properties: {
         a[3.14] = 3;
         a.if = 4;
         a["foo bar"] = 5;
-        a[NaN] = 6;
-        a[null] = 7;
+        a.NaN = 6;
+        a.null = 7;
         a[void 0] = 8;
     }
 }
 
 evaluate_array_length: {
     options = {
+        evaluate: true,
         properties: true,
         unsafe: true,
-        evaluate: true
-    };
+    }
     input: {
         a = [1, 2, 3].length;
         a = [1, 2, 3].join()["len" + "gth"];
@@ -109,10 +112,10 @@ evaluate_array_length: {
 
 evaluate_string_length: {
     options = {
+        evaluate: true,
         properties: true,
         unsafe: true,
-        evaluate: true
-    };
+    }
     input: {
         a = "foo".length;
         a = ("foo" + "bar")["len" + "gth"];
@@ -151,7 +154,8 @@ mangle_properties: {
 
 mangle_unquoted_properties: {
     options = {
-        properties: false
+        evaluate: true,
+        properties: false,
     }
     mangle = {
         properties: {
@@ -249,7 +253,8 @@ mangle_debug_suffix: {
 
 mangle_debug_suffix_keep_quoted: {
     options = {
-        properties: false
+        evaluate: true,
+        properties: false,
     }
     mangle = {
         properties: {
@@ -833,18 +838,29 @@ lhs_prop_2: {
         unused: true,
     }
     input: {
+        [1][0] = 42;
         (function(a) {
-            a[2] = "g";
+            a.b = "g";
         })("abc");
+        (function(a) {
+            a[2] = "g";
+        })("def");
+        (function(a) {
+            a[""] = "g";
+        })("ghi");
     }
     expect: {
-        "abc"[2] = "g";
+        [1][0] = 42;
+        "abc".b = "g";
+        "def"[2] = "g";
+        "ghi"[""] = "g";
     }
 }
 
 literal_duplicate_key_side_effects: {
     options = {
         properties: true,
+        side_effects: true,
     }
     input: {
         console.log({
@@ -864,6 +880,7 @@ prop_side_effects_1: {
         inline: true,
         properties: true,
         reduce_vars: true,
+        side_effects: true,
         toplevel: true,
         unused: true,
     }
@@ -899,6 +916,7 @@ prop_side_effects_2: {
         passes: 2,
         properties: true,
         reduce_vars: true,
+        side_effects: true,
         toplevel: true,
         unused: true,
     }
@@ -906,11 +924,11 @@ prop_side_effects_2: {
         var C = 1;
         console.log(C);
         var obj = {
-            bar: function() {
+            "": function() {
                 return C + C;
             }
         };
-        console.log(obj.bar());
+        console.log(obj[""]());
     }
     expect: {
         console.log(1);
@@ -974,6 +992,7 @@ accessor_2: {
 array_hole: {
     options = {
         properties: true,
+        side_effects: true,
     }
     input: {
         console.log(
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index ac4fa40..d7fdee1 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -2973,6 +2973,7 @@ obj_var_2: {
         passes: 2,
         properties: true,
         reduce_vars: true,
+        side_effects: true,
         toplevel: true,
         unsafe: true,
         unused: true,

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list