Merge branch 'master' into harmony
This commit is contained in:
@@ -183,9 +183,18 @@ merge(Compressor.prototype, {
|
|||||||
value: val
|
value: val
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
case "number":
|
case "number":
|
||||||
return make_node(isNaN(val) ? AST_NaN : AST_Number, orig, {
|
if (isNaN(val)) {
|
||||||
value: val
|
return make_node(AST_NaN, orig);
|
||||||
}).optimize(compressor);
|
}
|
||||||
|
|
||||||
|
if ((1 / val) < 0) {
|
||||||
|
return make_node(AST_UnaryPrefix, orig, {
|
||||||
|
operator: "-",
|
||||||
|
expression: make_node(AST_Number, null, { value: -val })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_node(AST_Number, orig, { value: val }).optimize(compressor);
|
||||||
case "boolean":
|
case "boolean":
|
||||||
return make_node(val ? AST_True : AST_False, orig).optimize(compressor);
|
return make_node(val ? AST_True : AST_False, orig).optimize(compressor);
|
||||||
case "undefined":
|
case "undefined":
|
||||||
@@ -542,6 +551,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function handle_if_return(statements, compressor) {
|
function handle_if_return(statements, compressor) {
|
||||||
var self = compressor.self();
|
var self = compressor.self();
|
||||||
|
var multiple_if_returns = has_multiple_if_returns(statements);
|
||||||
var in_lambda = self instanceof AST_Lambda;
|
var in_lambda = self instanceof AST_Lambda;
|
||||||
var ret = [];
|
var ret = [];
|
||||||
loop: for (var i = statements.length; --i >= 0;) {
|
loop: for (var i = statements.length; --i >= 0;) {
|
||||||
@@ -579,7 +589,8 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
//---
|
//---
|
||||||
// if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined;
|
// 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;
|
CHANGED = true;
|
||||||
stat = stat.clone();
|
stat = stat.clone();
|
||||||
stat.alternative = ret[0] || make_node(AST_Return, stat, {
|
stat.alternative = ret[0] || make_node(AST_Return, stat, {
|
||||||
@@ -671,6 +682,17 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
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) {
|
function eliminate_dead_code(statements, compressor) {
|
||||||
@@ -1051,10 +1073,7 @@ merge(Compressor.prototype, {
|
|||||||
return typeof e;
|
return typeof e;
|
||||||
case "void": return void ev(e, compressor);
|
case "void": return void ev(e, compressor);
|
||||||
case "~": return ~ev(e, compressor);
|
case "~": return ~ev(e, compressor);
|
||||||
case "-":
|
case "-": return -ev(e, compressor);
|
||||||
e = ev(e, compressor);
|
|
||||||
if (e === 0) throw def;
|
|
||||||
return -e;
|
|
||||||
case "+": return +ev(e, compressor);
|
case "+": return +ev(e, compressor);
|
||||||
}
|
}
|
||||||
throw def;
|
throw def;
|
||||||
|
|||||||
39
test/compress/evaluate.js
Normal file
39
test/compress/evaluate.js
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
negative_zero: {
|
||||||
|
options = { evaluate: true }
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
-"",
|
||||||
|
- -"",
|
||||||
|
1 / (-0),
|
||||||
|
1 / (-"")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(
|
||||||
|
-0,
|
||||||
|
0,
|
||||||
|
1 / (-0),
|
||||||
|
1 / (-0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
positive_zero: {
|
||||||
|
options = { evaluate: true }
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
+"",
|
||||||
|
+ -"",
|
||||||
|
1 / (+0),
|
||||||
|
1 / (+"")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(
|
||||||
|
0,
|
||||||
|
-0,
|
||||||
|
1 / (0),
|
||||||
|
1 / (0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
207
test/compress/if_return.js
Normal file
207
test/compress/if_return.js
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user