fix corner cases in typeofs (#5286)
This commit is contained in:
@@ -8764,14 +8764,40 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!body) return;
|
if (!body) return;
|
||||||
|
var abort = false;
|
||||||
var def = sym.definition();
|
var def = sym.definition();
|
||||||
var tw = new TreeWalker(function(node) {
|
var fn;
|
||||||
if (node instanceof AST_Scope) {
|
var tw = new TreeWalker(function(node, descend) {
|
||||||
var parent = tw.parent();
|
if (abort) return true;
|
||||||
if (parent instanceof AST_Call && parent.expression === node) return;
|
if (node instanceof AST_Assign) {
|
||||||
|
var ref = node.left;
|
||||||
|
if (!(ref instanceof AST_SymbolRef && ref.definition() === def)) return;
|
||||||
|
node.right.walk(tw);
|
||||||
|
switch (node.operator) {
|
||||||
|
case "=":
|
||||||
|
case "&&=":
|
||||||
|
abort = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Call) {
|
||||||
|
descend();
|
||||||
|
fn = node.expression.tail_node();
|
||||||
|
if (fn instanceof AST_Lambda) {
|
||||||
|
fn.walk(tw);
|
||||||
|
} else {
|
||||||
|
abort = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Scope) {
|
||||||
|
if (node === fn) return;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_SymbolRef) {
|
||||||
|
if (node.definition() === def) node.defined = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolRef && node.definition() === def) node.defined = true;
|
|
||||||
});
|
});
|
||||||
body.walk(tw);
|
body.walk(tw);
|
||||||
|
|
||||||
|
|||||||
@@ -436,6 +436,149 @@ emberjs_global: {
|
|||||||
expect_stdout: Error("PASS")
|
expect_stdout: Error("PASS")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reassign: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
conditionals: true,
|
||||||
|
passes: 2,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = console;
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else {
|
||||||
|
A = void 0;
|
||||||
|
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = console;
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else {
|
||||||
|
A = void 0;
|
||||||
|
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_call: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
conditionals: true,
|
||||||
|
passes: 2,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = console;
|
||||||
|
function f() {
|
||||||
|
A = void 0;
|
||||||
|
}
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else {
|
||||||
|
f();
|
||||||
|
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = console;
|
||||||
|
function f() {
|
||||||
|
A = void 0;
|
||||||
|
}
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else {
|
||||||
|
f();
|
||||||
|
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_conditional: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
conditionals: true,
|
||||||
|
passes: 2,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = console;
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else {
|
||||||
|
A &&= void 0;
|
||||||
|
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = console;
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else {
|
||||||
|
A &&= void 0;
|
||||||
|
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_iife: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
conditionals: true,
|
||||||
|
passes: 2,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = console;
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else (function() {
|
||||||
|
A = void 0;
|
||||||
|
})(console.log(void 0 === A ? "FAIL 2" : "PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = console;
|
||||||
|
"undefined" == typeof A ? console.log("FAIL 1") : function() {
|
||||||
|
A = void 0;
|
||||||
|
}(console.log((A, false) ? "FAIL 2" : "PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_property: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
conditionals: true,
|
||||||
|
passes: 2,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = console;
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else {
|
||||||
|
A.p = void 0;
|
||||||
|
while (console.log(void 0 === A ? "FAIL 2" : "PASS"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = console;
|
||||||
|
if ("undefined" == typeof A)
|
||||||
|
console.log("FAIL 1");
|
||||||
|
else {
|
||||||
|
A.p = void 0;
|
||||||
|
while (console.log((A, false) ? "FAIL 2" : "PASS"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
issue_3817: {
|
issue_3817: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user