fix LHS cases for NaN & friends (#1804)
`Infinity = beyond` should not become `1/0 = beyond`
This commit is contained in:
@@ -404,7 +404,7 @@ merge(Compressor.prototype, {
|
||||
|
||||
function is_modified(node, level, func) {
|
||||
var parent = tw.parent(level);
|
||||
if (isLHS(node, parent)
|
||||
if (is_lhs(node, parent)
|
||||
|| !func && parent instanceof AST_Call && parent.expression === node) {
|
||||
return true;
|
||||
} else if (parent instanceof AST_PropAccess && parent.expression === node) {
|
||||
@@ -697,7 +697,7 @@ merge(Compressor.prototype, {
|
||||
return statements;
|
||||
|
||||
function is_lvalue(node, parent) {
|
||||
return node instanceof AST_SymbolRef && isLHS(node, parent);
|
||||
return node instanceof AST_SymbolRef && is_lhs(node, parent);
|
||||
}
|
||||
function replace_var(node, parent, is_constant) {
|
||||
if (is_lvalue(node, parent)) return node;
|
||||
@@ -1299,9 +1299,9 @@ merge(Compressor.prototype, {
|
||||
|
||||
var unary_side_effects = makePredicate("delete ++ --");
|
||||
|
||||
function isLHS(node, parent) {
|
||||
return parent instanceof AST_Unary && unary_side_effects(parent.operator)
|
||||
|| parent instanceof AST_Assign && parent.left === node;
|
||||
function is_lhs(node, parent) {
|
||||
if (parent instanceof AST_Unary && unary_side_effects(parent.operator)) return parent.expression;
|
||||
if (parent instanceof AST_Assign && parent.left === node) return node;
|
||||
}
|
||||
|
||||
(function (def){
|
||||
@@ -1314,7 +1314,7 @@ merge(Compressor.prototype, {
|
||||
node = parent;
|
||||
parent = compressor.parent(level++);
|
||||
} while (parent instanceof AST_PropAccess && parent.expression === node);
|
||||
if (isLHS(node, parent)) {
|
||||
if (is_lhs(node, parent)) {
|
||||
compressor.warn('global_defs ' + this.print_to_string() + ' redefined [{file}:{line},{col}]', this.start);
|
||||
} else {
|
||||
return def;
|
||||
@@ -3620,12 +3620,8 @@ merge(Compressor.prototype, {
|
||||
return self;
|
||||
});
|
||||
|
||||
function in_delete(parent) {
|
||||
return parent instanceof AST_UnaryPrefix && parent.operator == "delete";
|
||||
}
|
||||
|
||||
function is_atomic(parent, self) {
|
||||
return parent.expression instanceof AST_SymbolRef || parent.expression.TYPE === self.TYPE;
|
||||
function is_atomic(lhs, self) {
|
||||
return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
|
||||
}
|
||||
|
||||
OPT(AST_Undefined, function(self, compressor){
|
||||
@@ -3641,8 +3637,8 @@ merge(Compressor.prototype, {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
var parent = compressor.parent();
|
||||
if (in_delete(parent) && is_atomic(parent, self)) return self;
|
||||
var lhs = is_lhs(compressor.self(), compressor.parent());
|
||||
if (lhs && is_atomic(lhs, self)) return self;
|
||||
return make_node(AST_UnaryPrefix, self, {
|
||||
operator: "void",
|
||||
expression: make_node(AST_Number, self, {
|
||||
@@ -3652,11 +3648,10 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
|
||||
OPT(AST_Infinity, function(self, compressor){
|
||||
var parent = compressor.parent();
|
||||
var del = in_delete(parent);
|
||||
if (del && is_atomic(parent, self)) return self;
|
||||
var lhs = is_lhs(compressor.self(), compressor.parent());
|
||||
if (lhs && is_atomic(lhs, self)) return self;
|
||||
if (compressor.option("keep_infinity")
|
||||
&& !(del && !is_atomic(parent, self))
|
||||
&& !(lhs && !is_atomic(lhs, self))
|
||||
&& !find_variable(compressor, "Infinity"))
|
||||
return self;
|
||||
return make_node(AST_Binary, self, {
|
||||
@@ -3671,8 +3666,8 @@ merge(Compressor.prototype, {
|
||||
});
|
||||
|
||||
OPT(AST_NaN, function(self, compressor){
|
||||
var parent = compressor.parent();
|
||||
if (in_delete(parent) && !is_atomic(parent, self)
|
||||
var lhs = is_lhs(compressor.self(), compressor.parent());
|
||||
if (lhs && !is_atomic(lhs, self)
|
||||
|| find_variable(compressor, "NaN")) {
|
||||
return make_node(AST_Binary, self, {
|
||||
operator: "/",
|
||||
|
||||
@@ -957,3 +957,35 @@ delete_binary_2: {
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
Infinity_NaN_undefined_LHS: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
Infinity = Infinity;
|
||||
++Infinity;
|
||||
Infinity--;
|
||||
NaN *= NaN;
|
||||
++NaN;
|
||||
NaN--;
|
||||
undefined |= undefined;
|
||||
++undefined;
|
||||
undefined--;
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
"function f() {",
|
||||
" Infinity = 1 / 0;",
|
||||
" ++Infinity;",
|
||||
" Infinity--;",
|
||||
" NaN *= NaN;",
|
||||
" ++NaN;",
|
||||
" NaN--;",
|
||||
" undefined |= void 0;",
|
||||
" ++undefined;",
|
||||
" undefined--;",
|
||||
"}",
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user