From be80f7e706cd6eb1c5f06e433804fda589a8968a Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Fri, 10 Mar 2017 11:27:30 +0800 Subject: [PATCH 1/4] support multi-line string in tests (#1590) `expect_exact` sometimes have multiple lines and `\n` are hard to read. Use array of strings to emulate line breaks and improve readability. --- test/compress/loops.js | 50 ++++++++++++++++++++++++++++++++--- test/compress/max_line_len.js | 15 +++++++++-- test/run-tests.js | 24 ++++++++++++----- 3 files changed, 77 insertions(+), 12 deletions(-) diff --git a/test/compress/loops.js b/test/compress/loops.js index df3011cd..7581e758 100644 --- a/test/compress/loops.js +++ b/test/compress/loops.js @@ -295,7 +295,15 @@ issue_186_beautify: { else bar(); } - expect_exact: 'var x = 3;\n\nif (foo()) do {\n do {\n alert(x);\n } while (--x);\n} while (x); else bar();' + expect_exact: [ + 'var x = 3;', + '', + 'if (foo()) do {', + ' do {', + ' alert(x);', + ' } while (--x);', + '} while (x); else bar();', + ] } issue_186_beautify_ie8: { @@ -314,7 +322,17 @@ issue_186_beautify_ie8: { else bar(); } - expect_exact: 'var x = 3;\n\nif (foo()) {\n do {\n do {\n alert(x);\n } while (--x);\n } while (x);\n} else bar();' + expect_exact: [ + 'var x = 3;', + '', + 'if (foo()) {', + ' do {', + ' do {', + ' alert(x);', + ' } while (--x);', + ' } while (x);', + '} else bar();', + ] } issue_186_bracketize: { @@ -374,7 +392,19 @@ issue_186_beautify_bracketize: { else bar(); } - expect_exact: 'var x = 3;\n\nif (foo()) {\n do {\n do {\n alert(x);\n } while (--x);\n } while (x);\n} else {\n bar();\n}' + expect_exact: [ + 'var x = 3;', + '', + 'if (foo()) {', + ' do {', + ' do {', + ' alert(x);', + ' } while (--x);', + ' } while (x);', + '} else {', + ' bar();', + '}', + ] } issue_186_beautify_bracketize_ie8: { @@ -394,5 +424,17 @@ issue_186_beautify_bracketize_ie8: { else bar(); } - expect_exact: 'var x = 3;\n\nif (foo()) {\n do {\n do {\n alert(x);\n } while (--x);\n } while (x);\n} else {\n bar();\n}' + expect_exact: [ + 'var x = 3;', + '', + 'if (foo()) {', + ' do {', + ' do {', + ' alert(x);', + ' } while (--x);', + ' } while (x);', + '} else {', + ' bar();', + '}', + ] } diff --git a/test/compress/max_line_len.js b/test/compress/max_line_len.js index b9e09178..7ad9ee0e 100644 --- a/test/compress/max_line_len.js +++ b/test/compress/max_line_len.js @@ -7,7 +7,13 @@ too_short: { return { c: 42, d: a(), e: "foo"}; } } - expect_exact: 'function f(a){\nreturn{\nc:42,\nd:a(),\ne:"foo"}}' + expect_exact: [ + 'function f(a){', + 'return{', + 'c:42,', + 'd:a(),', + 'e:"foo"}}', + ] expect_warnings: [ "WARN: Output exceeds 10 characters" ] @@ -22,7 +28,12 @@ just_enough: { return { c: 42, d: a(), e: "foo"}; } } - expect_exact: 'function f(a){\nreturn{c:42,\nd:a(),e:"foo"}\n}' + expect_exact: [ + 'function f(a){', + 'return{c:42,', + 'd:a(),e:"foo"}', + '}', + ] expect_warnings: [ ] } diff --git a/test/run-tests.js b/test/run-tests.js index 15a12c6b..36d26ef7 100755 --- a/test/run-tests.js +++ b/test/run-tests.js @@ -214,6 +214,23 @@ function parse_test(file) { })); } + function read_string(stat) { + if (stat.TYPE === "SimpleStatement") { + var body = stat.body; + out: switch(body.TYPE) { + case "String": + return body.value; + case "Array": + return body.elements.map(function(element) { + if (element.TYPE !== "String") + throw new Error("Should be array of strings"); + return element.value; + }).join("\n"); + } + } + throw new Error("Should be string or array of strings"); + } + function get_one_test(name, block) { var test = { name: name, options: {} }; var tw = new U.TreeWalker(function(node, descend){ @@ -240,12 +257,7 @@ function parse_test(file) { else if (stat.body.length == 0) stat = new U.AST_EmptyStatement(); } if (node.label.name === "expect_exact") { - if (!(stat.TYPE === "SimpleStatement" && stat.body.TYPE === "String")) { - throw new Error( - "The value of the expect_exact clause should be a string, " + - "like `expect_exact: \"some.exact.javascript;\"`"); - } - test[node.label.name] = stat.body.start.value + test[node.label.name] = read_string(stat); } else { test[node.label.name] = stat; } From d9344f30b83ecdfc8310ff43b9361c67cc85ec3e Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 11 Mar 2017 03:34:55 +0800 Subject: [PATCH 2/4] disallow parameter substitution for named IIFEs (#1596) Self-referenced function has non-fixed values assigned to its parameters. Let `unused` & `!keep_fnames` do the scanning, then apply `reduce_vars` only to unnamed functions. fixes #1595 --- lib/compress.js | 1 + test/compress/reduce_vars.js | 75 ++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/lib/compress.js b/lib/compress.js index 3964636f..7302f5b9 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -279,6 +279,7 @@ merge(Compressor.prototype, { } var iife; if (node instanceof AST_Function + && !node.name && (iife = tw.parent()) instanceof AST_Call && iife.expression === node) { // Virtually turn IIFE parameters into variable definitions: diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js index 734ce4ed..a5ab59f9 100644 --- a/test/compress/reduce_vars.js +++ b/test/compress/reduce_vars.js @@ -1252,3 +1252,78 @@ iife_func_side_effects: { })(x(), 0, z()); } } + +issue_1595_1: { + options = { + evaluate: true, + reduce_vars: true, + unused: true, + } + input: { + (function f(a) { + return f(a + 1); + })(2); + } + expect: { + (function f(a) { + return f(a + 1); + })(2); + } +} + +issue_1595_2: { + options = { + evaluate: true, + reduce_vars: true, + unused: true, + } + input: { + (function f(a) { + return g(a + 1); + })(2); + } + expect: { + (function(a) { + return g(a + 1); + })(2); + } +} + +issue_1595_3: { + options = { + evaluate: true, + passes: 2, + reduce_vars: true, + unused: true, + } + input: { + (function f(a) { + return g(a + 1); + })(2); + } + expect: { + (function(a) { + return g(3); + })(); + } +} + +issue_1595_4: { + options = { + evaluate: true, + reduce_vars: true, + unused: true, + } + input: { + (function iife(a, b, c) { + console.log(a, b, c); + if (a) iife(a - 1, b, c); + })(3, 4, 5); + } + expect: { + (function iife(a, b, c) { + console.log(a, b, c); + if (a) iife(a - 1, b, c); + })(3, 4, 5); + } +} From e3a3db73ae4c2c90ad304e1e6b7d019053ca3dc3 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 11 Mar 2017 04:59:55 +0800 Subject: [PATCH 3/4] temporary fix for boolean bug (#1597) fixes #1592 --- lib/compress.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compress.js b/lib/compress.js index 7302f5b9..e3ae5bde 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -404,7 +404,7 @@ merge(Compressor.prototype, { return make_node(AST_Number, orig, { value: val }); case "boolean": - return make_node(val ? AST_True : AST_False, orig).transform(compressor); + return make_node(val ? AST_True : AST_False, orig).optimize(compressor); case "undefined": return make_node(AST_Undefined, orig).transform(compressor); default: From 919d5e348249f7b8c5ef0581660817292b5308a6 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Sat, 11 Mar 2017 05:00:55 +0800 Subject: [PATCH 4/4] v2.8.12 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0a5d814d..2ba24c7c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "homepage": "http://lisperator.net/uglifyjs", "author": "Mihai Bazon (http://lisperator.net/)", "license": "BSD-2-Clause", - "version": "2.8.11", + "version": "2.8.12", "engines": { "node": ">=0.8.0" },