From: kzc Date: Sun, 22 May 2016 15:35:41 +0000 (-0400) Subject: Optimize if_return for single if/return cases. X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=1e390269d47e2a555f511556590d826938d572f9;p=UglifyJS.git Optimize if_return for single if/return cases. Fixes #1089 --- diff --git a/lib/compress.js b/lib/compress.js index 419c6a25..e78ee32b 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -535,6 +535,7 @@ merge(Compressor.prototype, { function handle_if_return(statements, compressor) { var self = compressor.self(); + var multiple_if_returns = has_multiple_if_returns(statements); var in_lambda = self instanceof AST_Lambda; var ret = []; loop: for (var i = statements.length; --i >= 0;) { @@ -572,7 +573,8 @@ merge(Compressor.prototype, { } //--- // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined; - if ((ret.length == 0 || ret[0] instanceof AST_Return) && stat.body.value && !stat.alternative && in_lambda) { + if (multiple_if_returns && (ret.length == 0 || ret[0] instanceof AST_Return) + && stat.body.value && !stat.alternative && in_lambda) { CHANGED = true; stat = stat.clone(); stat.alternative = ret[0] || make_node(AST_Return, stat, { @@ -664,6 +666,17 @@ merge(Compressor.prototype, { } } return ret; + + function has_multiple_if_returns(statements) { + var n = 0; + for (var i = statements.length; --i >= 0;) { + var stat = statements[i]; + if (stat instanceof AST_If && stat.body instanceof AST_Return) { + if (++n > 1) return true; + } + } + return false; + } }; function eliminate_dead_code(statements, compressor) { diff --git a/test/compress/if_return.js b/test/compress/if_return.js new file mode 100644 index 00000000..78a6e818 --- /dev/null +++ b/test/compress/if_return.js @@ -0,0 +1,207 @@ +if_return_1: { + options = { + if_return : true, + sequences : true, + conditionals : true, + comparisons : true, + evaluate : true, + booleans : true, + unused : true, + side_effects : true, + dead_code : true, + } + input: { + function f(x) { + if (x) { + return true; + } + } + } + expect: { + function f(x){if(x)return!0} + } +} + +if_return_2: { + options = { + if_return : true, + sequences : true, + conditionals : true, + comparisons : true, + evaluate : true, + booleans : true, + unused : true, + side_effects : true, + dead_code : true, + } + input: { + function f(x, y) { + if (x) + return 3; + if (y) + return c(); + } + } + expect: { + function f(x,y){return x?3:y?c():void 0} + } +} + +if_return_3: { + options = { + if_return : true, + sequences : true, + conditionals : true, + comparisons : true, + evaluate : true, + booleans : true, + unused : true, + side_effects : true, + dead_code : true, + } + input: { + function f(x) { + a(); + if (x) { + b(); + return false; + } + } + } + expect: { + function f(x){if(a(),x)return b(),!1} + } +} + +if_return_4: { + options = { + if_return : true, + sequences : true, + conditionals : true, + comparisons : true, + evaluate : true, + booleans : true, + unused : true, + side_effects : true, + dead_code : true, + } + input: { + function f(x, y) { + a(); + if (x) return 3; + b(); + if (y) return c(); + } + } + expect: { + function f(x,y){return a(),x?3:(b(),y?c():void 0)} + } +} + +if_return_5: { + options = { + if_return : true, + sequences : true, + conditionals : true, + comparisons : true, + evaluate : true, + booleans : true, + unused : true, + side_effects : true, + dead_code : true, + } + input: { + function f() { + if (x) + return; + return 7; + if (y) + return j; + } + } + expect: { + function f(){if(!x)return 7} + } +} + +if_return_6: { + options = { + if_return : true, + sequences : true, + conditionals : true, + comparisons : true, + evaluate : true, + booleans : true, + unused : true, + side_effects : true, + dead_code : true, + } + input: { + function f(x) { + return x ? true : void 0; + return y; + } + } + expect: { + // suboptimal + function f(x){return!!x||void 0} + } +} + +if_return_7: { + options = { + if_return : true, + sequences : true, + conditionals : true, + comparisons : true, + evaluate : true, + booleans : true, + unused : true, + side_effects : true, + dead_code : true, + } + input: { + function f(x) { + if (x) { + return true; + } + foo(); + bar(); + } + } + expect: { + // suboptimal + function f(x){return!!x||(foo(),void bar())} + } +} + +issue_1089: { + options = { + if_return : true, + sequences : true, + conditionals : true, + comparisons : true, + evaluate : true, + booleans : true, + unused : true, + side_effects : true, + dead_code : true, + } + input: { + function x() { + var f = document.getElementById("fname"); + if (f.files[0].size > 12345) { + alert("alert"); + f.focus(); + return false; + } + } + } + expect: { + function x() { + var f = document.getElementById("fname"); + if (f.files[0].size > 12345) + return alert("alert"), f.focus(), !1; + } + } +}