fix corner case in typeofs (#3818)

fixes #3817
This commit is contained in:
Alex Lam S.L
2020-04-24 18:29:42 +01:00
committed by GitHub
parent 3ee13cae02
commit 3a4497a1c3
2 changed files with 46 additions and 9 deletions

View File

@@ -5194,16 +5194,17 @@ merge(Compressor.prototype, {
return if_break_in_loop(self, compressor); return if_break_in_loop(self, compressor);
}); });
function mark_locally_defined(condition, consequent, alternative, operator) { function mark_locally_defined(condition, consequent, alternative) {
if (!(condition instanceof AST_Binary)) return; if (!(condition instanceof AST_Binary)) return;
if (!(condition.left instanceof AST_String)) { if (!(condition.left instanceof AST_String)) {
if (!operator) operator = condition.operator; switch (condition.operator) {
if (condition.operator != operator) return;
switch (operator) {
case "&&": case "&&":
mark_locally_defined(condition.left, consequent);
mark_locally_defined(condition.right, consequent);
break;
case "||": case "||":
mark_locally_defined(condition.left, consequent, alternative, operator); mark_locally_defined(negate(condition.left), alternative);
mark_locally_defined(condition.right, consequent, alternative, operator); mark_locally_defined(negate(condition.right), alternative);
break; break;
} }
return; return;
@@ -5235,6 +5236,20 @@ merge(Compressor.prototype, {
if (node instanceof AST_SymbolRef && node.definition() === def) node.defined = true; if (node instanceof AST_SymbolRef && node.definition() === def) node.defined = true;
}); });
body.walk(tw); body.walk(tw);
function negate(node) {
if (!(node instanceof AST_Binary)) return;
switch (node.operator) {
case "==":
node = node.clone();
node.operator = "!=";
return node;
case "!=":
node = node.clone();
node.operator = "==";
return node;
}
}
} }
OPT(AST_If, function(self, compressor) { OPT(AST_If, function(self, compressor) {
@@ -6623,7 +6638,7 @@ merge(Compressor.prototype, {
(self.left.is_number(compressor) && self.right.is_number(compressor)) || (self.left.is_number(compressor) && self.right.is_number(compressor)) ||
(self.left.is_boolean(compressor) && self.right.is_boolean(compressor)) || (self.left.is_boolean(compressor) && self.right.is_boolean(compressor)) ||
self.left.equivalent_to(self.right)) { self.left.equivalent_to(self.right)) {
self.operator = self.operator.substr(0, 2); self.operator = self.operator.slice(0, 2);
} }
// XXX: intentionally falling down to the next case // XXX: intentionally falling down to the next case
case "==": case "==":
@@ -7102,10 +7117,10 @@ merge(Compressor.prototype, {
} }
if (compressor.option("typeofs")) switch (self.operator) { if (compressor.option("typeofs")) switch (self.operator) {
case "&&": case "&&":
mark_locally_defined(self.left, self.right, null, "&&"); mark_locally_defined(self.left, self.right, null);
break; break;
case "||": case "||":
mark_locally_defined(self.left, null, self.right, "||"); mark_locally_defined(self.left, null, self.right);
break; break;
} }
if (compressor.option("unsafe")) { if (compressor.option("unsafe")) {

View File

@@ -435,3 +435,25 @@ emberjs_global: {
} }
expect_stdout: Error("PASS") expect_stdout: Error("PASS")
} }
issue_3817: {
options = {
comparisons: true,
conditionals: true,
passes: 2,
typeofs: true,
}
input: {
if ("A" == typeof A || !console.log("PASS")) switch (false) {
case "undefined" == typeof A:
console.log("FAIL");
}
}
expect: {
if ("A" == typeof A || !console.log("PASS")) switch (false) {
case "undefined" == typeof A:
console.log("FAIL");
}
}
expect_stdout: "PASS"
}