fix typeof side effects (#1696)
`statement_to_expression()` drops `typeof` even if it operates on undeclared variables. Since we now have `drop_side_effect_free()`, replace and remove this deprecated functionality.
This commit is contained in:
@@ -482,15 +482,6 @@ merge(Compressor.prototype, {
|
|||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
|
|
||||||
var readOnlyPrefix = makePredicate("! ~ + - void typeof");
|
|
||||||
function statement_to_expression(stat) {
|
|
||||||
if (stat.body instanceof AST_UnaryPrefix && readOnlyPrefix(stat.body.operator)) {
|
|
||||||
return stat.body.expression;
|
|
||||||
} else {
|
|
||||||
return stat.body;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function is_iife_call(node) {
|
function is_iife_call(node) {
|
||||||
if (node instanceof AST_Call && !(node instanceof AST_New)) {
|
if (node instanceof AST_Call && !(node instanceof AST_New)) {
|
||||||
return node.expression instanceof AST_Function || is_iife_call(node.expression);
|
return node.expression instanceof AST_Function || is_iife_call(node.expression);
|
||||||
@@ -984,10 +975,10 @@ merge(Compressor.prototype, {
|
|||||||
};
|
};
|
||||||
statements.forEach(function(stat){
|
statements.forEach(function(stat){
|
||||||
if (stat instanceof AST_SimpleStatement) {
|
if (stat instanceof AST_SimpleStatement) {
|
||||||
if (seqLength(seq) >= compressor.sequences_limit) {
|
if (seqLength(seq) >= compressor.sequences_limit) push_seq();
|
||||||
push_seq();
|
var body = stat.body;
|
||||||
}
|
if (seq.length > 0) body = body.drop_side_effect_free(compressor);
|
||||||
seq.push(seq.length > 0 ? statement_to_expression(stat) : stat.body);
|
if (body) seq.push(body);
|
||||||
} else {
|
} else {
|
||||||
push_seq();
|
push_seq();
|
||||||
ret.push(stat);
|
ret.push(stat);
|
||||||
@@ -1036,7 +1027,7 @@ merge(Compressor.prototype, {
|
|||||||
stat.init = cons_seq(stat.init);
|
stat.init = cons_seq(stat.init);
|
||||||
}
|
}
|
||||||
else if (!stat.init) {
|
else if (!stat.init) {
|
||||||
stat.init = statement_to_expression(prev);
|
stat.init = prev.body.drop_side_effect_free(compressor);
|
||||||
ret.pop();
|
ret.pop();
|
||||||
}
|
}
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
@@ -2170,6 +2161,7 @@ merge(Compressor.prototype, {
|
|||||||
switch (this.operator) {
|
switch (this.operator) {
|
||||||
case "&&":
|
case "&&":
|
||||||
case "||":
|
case "||":
|
||||||
|
if (right === this.right) return this;
|
||||||
var node = this.clone();
|
var node = this.clone();
|
||||||
node.right = right;
|
node.right = right;
|
||||||
return node;
|
return node;
|
||||||
@@ -2423,8 +2415,8 @@ merge(Compressor.prototype, {
|
|||||||
return make_node(AST_SimpleStatement, self, {
|
return make_node(AST_SimpleStatement, self, {
|
||||||
body: make_node(AST_Conditional, self, {
|
body: make_node(AST_Conditional, self, {
|
||||||
condition : self.condition,
|
condition : self.condition,
|
||||||
consequent : statement_to_expression(self.body),
|
consequent : self.body.body,
|
||||||
alternative : statement_to_expression(self.alternative)
|
alternative : self.alternative.body
|
||||||
})
|
})
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
@@ -2440,25 +2432,24 @@ merge(Compressor.prototype, {
|
|||||||
body: make_node(AST_Binary, self, {
|
body: make_node(AST_Binary, self, {
|
||||||
operator : "||",
|
operator : "||",
|
||||||
left : negated,
|
left : negated,
|
||||||
right : statement_to_expression(self.body)
|
right : self.body.body
|
||||||
})
|
})
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
return make_node(AST_SimpleStatement, self, {
|
return make_node(AST_SimpleStatement, self, {
|
||||||
body: make_node(AST_Binary, self, {
|
body: make_node(AST_Binary, self, {
|
||||||
operator : "&&",
|
operator : "&&",
|
||||||
left : self.condition,
|
left : self.condition,
|
||||||
right : statement_to_expression(self.body)
|
right : self.body.body
|
||||||
})
|
})
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
if (self.body instanceof AST_EmptyStatement
|
if (self.body instanceof AST_EmptyStatement
|
||||||
&& self.alternative
|
|
||||||
&& self.alternative instanceof AST_SimpleStatement) {
|
&& self.alternative instanceof AST_SimpleStatement) {
|
||||||
return make_node(AST_SimpleStatement, self, {
|
return make_node(AST_SimpleStatement, self, {
|
||||||
body: make_node(AST_Binary, self, {
|
body: make_node(AST_Binary, self, {
|
||||||
operator : "||",
|
operator : "||",
|
||||||
left : self.condition,
|
left : self.condition,
|
||||||
right : statement_to_expression(self.alternative)
|
right : self.alternative.body
|
||||||
})
|
})
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -353,8 +353,9 @@ issue_1254_negate_iife_nested: {
|
|||||||
|
|
||||||
issue_1288: {
|
issue_1288: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
|
negate_iife: true,
|
||||||
|
side_effects: false,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
if (w) ;
|
if (w) ;
|
||||||
@@ -374,11 +375,11 @@ issue_1288: {
|
|||||||
})(0);
|
})(0);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
w || function f() {}();
|
w || !function f() {}();
|
||||||
x || function() {
|
x || !function() {
|
||||||
x = {};
|
x = {};
|
||||||
}();
|
}();
|
||||||
y ? function() {}() : function(z) {
|
y ? !function() {}() : !function(z) {
|
||||||
return z;
|
return z;
|
||||||
}(0);
|
}(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -579,3 +579,17 @@ issue_1690_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if_switch_typeof: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (a) switch(typeof b) {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user