[Pkg-javascript-commits] [uglifyjs] 191/491: drop `unused` builtin globals under `unsafe` (#2236)

Jonas Smedegaard dr at jones.dk
Wed Feb 14 19:51:34 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 a5ffe2c23fdfaf13f3466a01d9dd9d590c5e8672
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date:   Sat Jul 15 15:16:11 2017 +0800

    drop `unused` builtin globals under `unsafe` (#2236)
    
    fixes #2233
---
 lib/compress.js            | 85 ++++++++++++++++++++++++----------------------
 lib/scope.js               |  8 -----
 test/compress/dead-code.js | 79 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 48 deletions(-)

diff --git a/lib/compress.js b/lib/compress.js
index 0330c68..6dc7b72 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -689,6 +689,16 @@ merge(Compressor.prototype, {
         return false;
     }
 
+    function is_undeclared_ref(node) {
+        return node instanceof AST_SymbolRef && node.definition().undeclared;
+    }
+
+    var global_names = makePredicate("Array Boolean console Error Function Math Number RegExp Object String");
+    AST_SymbolRef.DEFMETHOD("is_declared", function(compressor) {
+        return !this.definition().undeclared
+            || compressor.option("unsafe") && global_names(this.name);
+    });
+
     function tighten_body(statements, compressor) {
         var CHANGED, max_iter = 10;
         do {
@@ -758,7 +768,7 @@ merge(Compressor.prototype, {
                             || node instanceof AST_Call && lhs instanceof AST_PropAccess && lhs.equivalent_to(node.expression)
                             || node instanceof AST_Debugger
                             || node instanceof AST_IterationStatement && !(node instanceof AST_For)
-                            || node instanceof AST_SymbolRef && node.undeclared()
+                            || node instanceof AST_SymbolRef && !node.is_declared(compressor)
                             || node instanceof AST_Try
                             || node instanceof AST_With
                             || parent instanceof AST_For && node !== parent.init) {
@@ -1320,12 +1330,12 @@ merge(Compressor.prototype, {
     // returns true if this node may be null, undefined or contain `AST_Accessor`
     (function(def) {
         AST_Node.DEFMETHOD("may_throw_on_access", function(compressor) {
-            var pure_getters = compressor.option("pure_getters");
-            return !pure_getters || this._throw_on_access(pure_getters);
+            return !compressor.option("pure_getters")
+                || this._dot_throw(compressor);
         });
 
-        function is_strict(pure_getters) {
-            return /strict/.test(pure_getters);
+        function is_strict(compressor) {
+            return /strict/.test(compressor.option("pure_getters"));
         }
 
         def(AST_Node, is_strict);
@@ -1333,8 +1343,8 @@ merge(Compressor.prototype, {
         def(AST_Undefined, return_true);
         def(AST_Constant, return_false);
         def(AST_Array, return_false);
-        def(AST_Object, function(pure_getters) {
-            if (!is_strict(pure_getters)) return false;
+        def(AST_Object, function(compressor) {
+            if (!is_strict(compressor)) return false;
             for (var i = this.properties.length; --i >=0;)
                 if (this.properties[i].value instanceof AST_Accessor) return true;
             return false;
@@ -1344,37 +1354,38 @@ merge(Compressor.prototype, {
         def(AST_UnaryPrefix, function() {
             return this.operator == "void";
         });
-        def(AST_Binary, function(pure_getters) {
+        def(AST_Binary, function(compressor) {
             switch (this.operator) {
               case "&&":
-                return this.left._throw_on_access(pure_getters);
+                return this.left._dot_throw(compressor);
               case "||":
-                return this.left._throw_on_access(pure_getters)
-                    && this.right._throw_on_access(pure_getters);
+                return this.left._dot_throw(compressor)
+                    && this.right._dot_throw(compressor);
               default:
                 return false;
             }
         })
-        def(AST_Assign, function(pure_getters) {
+        def(AST_Assign, function(compressor) {
             return this.operator == "="
-                && this.right._throw_on_access(pure_getters);
+                && this.right._dot_throw(compressor);
         })
-        def(AST_Conditional, function(pure_getters) {
-            return this.consequent._throw_on_access(pure_getters)
-                || this.alternative._throw_on_access(pure_getters);
+        def(AST_Conditional, function(compressor) {
+            return this.consequent._dot_throw(compressor)
+                || this.alternative._dot_throw(compressor);
         })
-        def(AST_Sequence, function(pure_getters) {
-            return this.expressions[this.expressions.length - 1]._throw_on_access(pure_getters);
+        def(AST_Sequence, function(compressor) {
+            return this.expressions[this.expressions.length - 1]._dot_throw(compressor);
         });
-        def(AST_SymbolRef, function(pure_getters) {
+        def(AST_SymbolRef, function(compressor) {
             if (this.is_undefined) return true;
-            if (!is_strict(pure_getters)) return false;
+            if (!is_strict(compressor)) return false;
+            if (is_undeclared_ref(this) && this.is_declared(compressor)) return false;
             if (this.is_immutable()) return false;
             var fixed = this.fixed_value();
-            return !fixed || fixed._throw_on_access(pure_getters);
+            return !fixed || fixed._dot_throw(compressor);
         });
     })(function(node, func) {
-        node.DEFMETHOD("_throw_on_access", func);
+        node.DEFMETHOD("_dot_throw", func);
     });
 
     /* -----[ boolean/negation helpers ]----- */
@@ -1735,11 +1746,8 @@ merge(Compressor.prototype, {
         });
         var global_objs = {
             Array: Array,
-            Boolean: Boolean,
             Math: Math,
             Number: Number,
-            RegExp: RegExp,
-            Object: Object,
             String: String,
         };
         function convert_to_predicate(obj) {
@@ -1776,7 +1784,7 @@ merge(Compressor.prototype, {
                 }
                 var exp = this.expression;
                 var val;
-                if (exp instanceof AST_SymbolRef && exp.undeclared()) {
+                if (is_undeclared_ref(exp)) {
                     if (!(static_values[exp.name] || return_false)(key)) return this;
                     val = global_objs[exp.name];
                 } else {
@@ -1868,7 +1876,7 @@ merge(Compressor.prototype, {
                 }
                 var val;
                 var e = exp.expression;
-                if (e instanceof AST_SymbolRef && e.undeclared()) {
+                if (is_undeclared_ref(e)) {
                     if (!(static_fns[e.name] || return_false)(key)) return this;
                     val = global_objs[e.name];
                 } else {
@@ -2050,7 +2058,7 @@ merge(Compressor.prototype, {
                 || this.expression.has_side_effects(compressor);
         });
         def(AST_SymbolRef, function(compressor){
-            return this.undeclared();
+            return !this.is_declared(compressor);
         });
         def(AST_SymbolDeclaration, return_false);
         def(AST_Object, function(compressor){
@@ -2684,8 +2692,8 @@ merge(Compressor.prototype, {
             }
             return expression;
         });
-        def(AST_SymbolRef, function() {
-            return this.undeclared() ? this : null;
+        def(AST_SymbolRef, function(compressor) {
+            return this.is_declared(compressor) ? null : this;
         });
         def(AST_Object, function(compressor, first_in_statement){
             var values = trim(this.properties, compressor, first_in_statement);
@@ -3147,7 +3155,7 @@ merge(Compressor.prototype, {
             self.args.length = last;
         }
         if (compressor.option("unsafe")) {
-            if (exp instanceof AST_SymbolRef && exp.undeclared()) {
+            if (is_undeclared_ref(exp)) {
                 switch (exp.name) {
                   case "Array":
                     if (self.args.length != 1) {
@@ -3274,8 +3282,7 @@ merge(Compressor.prototype, {
             }
         }
         if (compressor.option("unsafe_Func")
-            && exp instanceof AST_SymbolRef
-            && exp.undeclared()
+            && is_undeclared_ref(exp)
             && exp.name == "Function") {
             // new Function() => function(){}
             if (self.args.length == 0) return make_node(AST_Function, self, {
@@ -3392,9 +3399,7 @@ merge(Compressor.prototype, {
                 while (name.expression) {
                     name = name.expression;
                 }
-                if (name instanceof AST_SymbolRef
-                    && name.name == "console"
-                    && name.undeclared()) {
+                if (is_undeclared_ref(name) && name.name == "console") {
                     return make_node(AST_Undefined, self).optimize(compressor);
                 }
             }
@@ -3415,7 +3420,7 @@ merge(Compressor.prototype, {
     OPT(AST_New, function(self, compressor){
         if (compressor.option("unsafe")) {
             var exp = self.expression;
-            if (exp instanceof AST_SymbolRef && exp.undeclared()) {
+            if (is_undeclared_ref(exp)) {
                 switch (exp.name) {
                   case "Object":
                   case "RegExp":
@@ -3709,7 +3714,7 @@ merge(Compressor.prototype, {
                 && self.right instanceof AST_UnaryPrefix
                 && self.right.operator == "typeof") {
                 var expr = self.right.expression;
-                if (expr instanceof AST_SymbolRef ? !expr.undeclared()
+                if (expr instanceof AST_SymbolRef ? expr.is_declared(compressor)
                     : !(expr instanceof AST_PropAccess && compressor.option("ie8"))) {
                     self.right = expr;
                     self.left = make_node(AST_Undefined, self.left).optimize(compressor);
@@ -4035,7 +4040,7 @@ merge(Compressor.prototype, {
         }
         // testing against !self.scope.uses_with first is an optimization
         if (!compressor.option("ie8")
-            && self.undeclared()
+            && is_undeclared_ref(self)
             && (!self.scope.uses_with || !compressor.find_parent(AST_With))) {
             switch (self.name) {
               case "undefined":
@@ -4454,7 +4459,7 @@ merge(Compressor.prototype, {
             && self.expression instanceof AST_Dot
             && self.expression.property == "prototype") {
             var exp = self.expression.expression;
-            if (exp instanceof AST_SymbolRef && exp.undeclared()) switch (exp.name) {
+            if (is_undeclared_ref(exp)) switch (exp.name) {
               case "Array":
                 self.expression = make_node(AST_Array, self.expression, {
                     elements: []
diff --git a/lib/scope.js b/lib/scope.js
index f8ecedb..df7b207 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -373,14 +373,6 @@ AST_Symbol.DEFMETHOD("unreferenced", function(){
         && !(this.scope.uses_eval || this.scope.uses_with);
 });
 
-AST_Symbol.DEFMETHOD("undeclared", function(){
-    return this.definition().undeclared;
-});
-
-AST_LabelRef.DEFMETHOD("undeclared", return_false);
-
-AST_Label.DEFMETHOD("undeclared", return_false);
-
 AST_Symbol.DEFMETHOD("definition", function(){
     return this.thedef;
 });
diff --git a/test/compress/dead-code.js b/test/compress/dead-code.js
index 0fcbbe4..abf5297 100644
--- a/test/compress/dead-code.js
+++ b/test/compress/dead-code.js
@@ -230,3 +230,82 @@ accessor: {
     }
     expect: {}
 }
+
+issue_2233_1: {
+    options = {
+        pure_getters: "strict",
+        side_effects: true,
+        unsafe: true,
+    }
+    input: {
+        Array.isArray;
+        Boolean;
+        console.log;
+        Error.name;
+        Function.length;
+        Math.random;
+        Number.isNaN;
+        RegExp;
+        Object.defineProperty;
+        String.fromCharCode;
+    }
+    expect: {}
+    expect_stdout: true
+}
+
+issue_2233_2: {
+    options = {
+        pure_getters: "strict",
+        reduce_vars: true,
+        side_effects: true,
+        unsafe: true,
+        unused: true,
+    }
+    input: {
+        var RegExp;
+        Array.isArray;
+        RegExp;
+        UndeclaredGlobal;
+        function foo() {
+            var Number;
+            AnotherUndeclaredGlobal;
+            Math.sin;
+            Number.isNaN;
+        }
+    }
+    expect: {
+        var RegExp;
+        UndeclaredGlobal;
+        function foo() {
+            var Number;
+            AnotherUndeclaredGlobal;
+            Number.isNaN;
+        }
+    }
+}
+
+issue_2233_3: {
+    options = {
+        pure_getters: "strict",
+        reduce_vars: true,
+        side_effects: true,
+        toplevel: true,
+        unsafe: true,
+        unused: true,
+    }
+    input: {
+        var RegExp;
+        Array.isArray;
+        RegExp;
+        UndeclaredGlobal;
+        function foo() {
+            var Number;
+            AnotherUndeclaredGlobal;
+            Math.sin;
+            Number.isNaN;
+        }
+    }
+    expect: {
+        UndeclaredGlobal;
+    }
+}

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