[Pkg-javascript-commits] [uglifyjs] 256/491: reduce `this` within functions (#2421)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:42 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 c8b6f4733d35db48b5b7e2373264db0d99eb299f
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Sat Nov 4 00:31:37 2017 +0800

    reduce `this` within functions (#2421)
    
    - only replace same-scope usages
    - augment `test/ufuzz.js` to test for `this`
    
    
    fixes #2420
---
 lib/compress.js              | 75 +++++++++++++++++++++++----------------
 test/compress/reduce_vars.js | 84 ++++++++++++++++++++++++++++++++++++++++++++
 test/ufuzz.js                |  1 +
 3 files changed, 129 insertions(+), 31 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 99ab7b7..f09f2b9 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -285,7 +285,7 @@ merge(Compressor.prototype, {
         self.transform(tt);
     });
 
-    AST_Node.DEFMETHOD("reset_opt_flags", function(compressor) {
+    AST_Toplevel.DEFMETHOD("reset_opt_flags", function(compressor) {
         var reduce_vars = compressor.option("reduce_vars");
         var unused = compressor.option("unused");
         // Stack of look-up tables to keep track of whether a `SymbolDef` has been
@@ -564,7 +564,10 @@ merge(Compressor.prototype, {
         }
 
         function is_immutable(value) {
-            return value && (value.is_constant() || value instanceof AST_Lambda);
+            if (!value) return false;
+            return value.is_constant()
+                || value instanceof AST_Lambda
+                || value instanceof AST_This;
         }
 
         function read_property(obj, key) {
@@ -4211,39 +4214,49 @@ merge(Compressor.prototype, {
                 var value = fixed.optimize(compressor);
                 return value === fixed ? fixed.clone(true) : value;
             }
-            if (compressor.option("evaluate") && fixed) {
-                if (d.should_replace === undefined) {
-                    var init = fixed.evaluate(compressor);
-                    if (init !== fixed && (compressor.option("unsafe_regexp") || !(init instanceof RegExp))) {
-                        init = make_node_from_constant(init, fixed);
-                        var value_length = init.optimize(compressor).print_to_string().length;
-                        var fn;
-                        if (has_symbol_ref(fixed)) {
-                            fn = function() {
-                                var result = init.optimize(compressor);
-                                return result === init ? result.clone(true) : result;
-                            };
-                        } else {
-                            value_length = Math.min(value_length, fixed.print_to_string().length);
-                            fn = function() {
-                                var result = best_of_expression(init.optimize(compressor), fixed);
-                                return result === init || result === fixed ? result.clone(true) : result;
-                            };
-                        }
-                        var name_length = d.name.length;
-                        var overhead = 0;
-                        if (compressor.option("unused") && !compressor.exposed(d)) {
-                            overhead = (name_length + 2 + value_length) / d.references.length;
-                        }
-                        d.should_replace = value_length <= name_length + overhead ? fn : false;
-                    } else {
-                        d.should_replace = false;
+            if (fixed && d.should_replace === undefined) {
+                var init;
+                if (fixed instanceof AST_This) {
+                    if (!(d.orig[0] instanceof AST_SymbolFunarg)
+                        && all(d.references, function(ref) {
+                            return d.scope === ref.scope;
+                        })) {
+                        init = fixed;
+                    }
+                } else {
+                    var ev = fixed.evaluate(compressor);
+                    if (ev !== fixed && (compressor.option("unsafe_regexp") || !(ev instanceof RegExp))) {
+                        init = make_node_from_constant(ev, fixed);
                     }
                 }
-                if (d.should_replace) {
-                    return d.should_replace();
+                if (init) {
+                    var value_length = init.optimize(compressor).print_to_string().length;
+                    var fn;
+                    if (has_symbol_ref(fixed)) {
+                        fn = function() {
+                            var result = init.optimize(compressor);
+                            return result === init ? result.clone(true) : result;
+                        };
+                    } else {
+                        value_length = Math.min(value_length, fixed.print_to_string().length);
+                        fn = function() {
+                            var result = best_of_expression(init.optimize(compressor), fixed);
+                            return result === init || result === fixed ? result.clone(true) : result;
+                        };
+                    }
+                    var name_length = d.name.length;
+                    var overhead = 0;
+                    if (compressor.option("unused") && !compressor.exposed(d)) {
+                        overhead = (name_length + 2 + value_length) / d.references.length;
+                    }
+                    d.should_replace = value_length <= name_length + overhead ? fn : false;
+                } else {
+                    d.should_replace = false;
                 }
             }
+            if (d.should_replace) {
+                return d.should_replace();
+            }
         }
         return self;
 
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index d7fdee1..e4d22e9 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -3295,3 +3295,87 @@ escaped_prop: {
     }
     expect_stdout: "2"
 }
+
+issue_2420_1: {
+    options = {
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        function run() {
+            var self = this;
+            if (self.count++)
+                self.foo();
+            else
+                self.bar();
+        }
+        var o = {
+            count: 0,
+            foo: function() { console.log("foo"); },
+            bar: function() { console.log("bar"); },
+        };
+        run.call(o);
+        run.call(o);
+    }
+    expect: {
+        function run() {
+            if (this.count++)
+                this.foo();
+            else
+                this.bar();
+        }
+        var o = {
+            count: 0,
+            foo: function() { console.log("foo"); },
+            bar: function() { console.log("bar"); },
+        };
+        run.call(o);
+        run.call(o);
+    }
+    expect_stdout: [
+        "bar",
+        "foo",
+    ]
+}
+
+issue_2420_2: {
+    options = {
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        function f() {
+            var that = this;
+            if (that.bar)
+                that.foo();
+            else
+                !function(that, self) {
+                    console.log(this === that, self === this, that === self);
+                }(that, this);
+        }
+        f.call({
+            bar: 1,
+            foo: function() { console.log("foo", this.bar); },
+        });
+        f.call({});
+    }
+    expect: {
+        function f() {
+            if (this.bar)
+                this.foo();
+            else
+                !function(that, self) {
+                    console.log(this === that, self === this, that === self);
+                }(this, this);
+        }
+        f.call({
+            bar: 1,
+            foo: function() { console.log("foo", this.bar); },
+        });
+        f.call({});
+    }
+    expect_stdout: [
+        "foo 1",
+        "false false true",
+    ]
+}
diff --git a/test/ufuzz.js b/test/ufuzz.js
index e38ffa2..d6a2a45 100644
--- a/test/ufuzz.js
+++ b/test/ufuzz.js
@@ -162,6 +162,7 @@ var VALUES = [
     '"object"',
     '"number"',
     '"function"',
+    'this',
 ];
 
 var BINARY_OPS_NO_COMMA = [

-- 
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