smarter const replacement taking name length into account
authorkzc <zaxxon2011@gmail.com>
Sat, 18 Feb 2017 11:12:57 +0000 (19:12 +0800)
committeralexlamsl <alexlamsl@gmail.com>
Tue, 21 Feb 2017 05:29:58 +0000 (13:29 +0800)
closes #1459

lib/compress.js
test/compress/const.js [new file with mode: 0644]

index b66c558..1f710f1 100644 (file)
@@ -2784,6 +2784,18 @@ merge(Compressor.prototype, {
                 }
             }
         }
+        if (compressor.option("evaluate") && !isLHS(self, compressor.parent())) {
+            var d = self.definition();
+            if (d && d.constant && d.init && d.init.is_constant(compressor)) {
+                var original_as_string = self.print_to_string();
+                var const_node = make_node_from_constant(compressor, d.init.constant_value(compressor), self);
+                var const_node_as_string = const_node.print_to_string();
+                var per_const_overhead = d.global || !d.references.length ? 0
+                    : (d.name.length + 2 + const_node_as_string.length) / d.references.length;
+                if (const_node_as_string.length <= original_as_string.length + per_const_overhead)
+                    return const_node;
+            }
+        }
         return self;
     });
 
diff --git a/test/compress/const.js b/test/compress/const.js
new file mode 100644 (file)
index 0000000..dd175fc
--- /dev/null
@@ -0,0 +1,161 @@
+issue_1191: {
+    options = {
+        evaluate      : true,
+        booleans      : true,
+        comparisons   : true,
+        dead_code     : true,
+        conditionals  : true,
+        side_effects  : true,
+        unused        : true,
+        hoist_funs    : true,
+        if_return     : true,
+        join_vars     : true,
+        sequences     : false,
+        collapse_vars : false,
+    }
+    input: {
+        function foo(rot) {
+            const rotTol = 5;
+            if (rot < -rotTol || rot > rotTol)
+                bar();
+            baz();
+        }
+    }
+    expect: {
+        function foo(rot) {
+            (rot < -5 || rot > 5) && bar();
+            baz();
+        }
+    }
+}
+
+issue_1194: {
+    options = {
+        evaluate      : true,
+        booleans      : true,
+        comparisons   : true,
+        dead_code     : true,
+        conditionals  : true,
+        side_effects  : true,
+        unused        : true,
+        hoist_funs    : true,
+        if_return     : true,
+        join_vars     : true,
+        sequences     : false,
+        collapse_vars : false,
+    }
+    input: {
+        function f1() {const a = "X"; return a + a;}
+        function f2() {const aa = "X"; return aa + aa;}
+        function f3() {const aaa = "X"; return aaa + aaa;}
+    }
+    expect: {
+        function f1(){return"XX"}
+        function f2(){return"XX"}
+        function f3(){return"XX"}
+    }
+}
+
+issue_1396: {
+    options = {
+        evaluate      : true,
+        booleans      : true,
+        comparisons   : true,
+        dead_code     : true,
+        conditionals  : true,
+        side_effects  : true,
+        unused        : true,
+        hoist_funs    : true,
+        if_return     : true,
+        join_vars     : true,
+        sequences     : false,
+        collapse_vars : false,
+    }
+    input: {
+        function foo(a) {
+            const VALUE = 1;
+            console.log(2 | VALUE);
+            console.log(VALUE + 1);
+            console.log(VALUE);
+            console.log(a & VALUE);
+        }
+        function bar() {
+            const s = "01234567890123456789";
+            console.log(s + s + s + s + s);
+
+            const CONSTANT = "abc";
+            console.log(CONSTANT + CONSTANT + CONSTANT + CONSTANT + CONSTANT);
+        }
+    }
+    expect: {
+        function foo(a) {
+            console.log(3);
+            console.log(2);
+            console.log(1);
+            console.log(1 & a);
+        }
+        function bar() {
+            const s = "01234567890123456789";
+            console.log(s + s + s + s + s);
+
+            console.log("abcabcabcabcabc");
+        }
+    }
+}
+
+unused_regexp_literal: {
+    options = {
+        evaluate      : true,
+        booleans      : true,
+        comparisons   : true,
+        dead_code     : true,
+        conditionals  : true,
+        side_effects  : true,
+        unused        : true,
+        hoist_funs    : true,
+        if_return     : true,
+        join_vars     : true,
+        sequences     : false,
+        collapse_vars : false,
+    }
+    input: {
+        function f(){ var a = /b/; }
+    }
+    expect: {
+        function f(){}
+    }
+}
+
+regexp_literal_not_const: {
+    options = {
+        evaluate      : true,
+        booleans      : true,
+        comparisons   : true,
+        dead_code     : true,
+        conditionals  : true,
+        side_effects  : true,
+        unused        : true,
+        hoist_funs    : true,
+        if_return     : true,
+        join_vars     : true,
+        sequences     : false,
+        collapse_vars : false,
+    }
+    input: {
+        (function(){
+            var result;
+            const s = 'acdabcdeabbb';
+            const REGEXP_LITERAL = /ab*/g;
+            while (result = REGEXP_LITERAL.exec(s)) {
+                console.log(result[0]);
+            }
+        })();
+    }
+    expect: {
+        (function() {
+            var result;
+            const REGEXP_LITERAL = /ab*/g;
+            while (result = REGEXP_LITERAL.exec("acdabcdeabbb")) console.log(result[0]);
+        })();
+    }
+}