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) {
|
function is_modified(node, level, func) {
|
||||||
var parent = tw.parent(level);
|
var parent = tw.parent(level);
|
||||||
if (isLHS(node, parent)
|
if (is_lhs(node, parent)
|
||||||
|| !func && parent instanceof AST_Call && parent.expression === node) {
|
|| !func && parent instanceof AST_Call && parent.expression === node) {
|
||||||
return true;
|
return true;
|
||||||
} else if (parent instanceof AST_PropAccess && parent.expression === node) {
|
} else if (parent instanceof AST_PropAccess && parent.expression === node) {
|
||||||
@@ -697,7 +697,7 @@ merge(Compressor.prototype, {
|
|||||||
return statements;
|
return statements;
|
||||||
|
|
||||||
function is_lvalue(node, parent) {
|
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) {
|
function replace_var(node, parent, is_constant) {
|
||||||
if (is_lvalue(node, parent)) return node;
|
if (is_lvalue(node, parent)) return node;
|
||||||
@@ -1299,9 +1299,9 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
var unary_side_effects = makePredicate("delete ++ --");
|
var unary_side_effects = makePredicate("delete ++ --");
|
||||||
|
|
||||||
function isLHS(node, parent) {
|
function is_lhs(node, parent) {
|
||||||
return parent instanceof AST_Unary && unary_side_effects(parent.operator)
|
if (parent instanceof AST_Unary && unary_side_effects(parent.operator)) return parent.expression;
|
||||||
|| parent instanceof AST_Assign && parent.left === node;
|
if (parent instanceof AST_Assign && parent.left === node) return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
(function (def){
|
(function (def){
|
||||||
@@ -1314,7 +1314,7 @@ merge(Compressor.prototype, {
|
|||||||
node = parent;
|
node = parent;
|
||||||
parent = compressor.parent(level++);
|
parent = compressor.parent(level++);
|
||||||
} while (parent instanceof AST_PropAccess && parent.expression === node);
|
} 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);
|
compressor.warn('global_defs ' + this.print_to_string() + ' redefined [{file}:{line},{col}]', this.start);
|
||||||
} else {
|
} else {
|
||||||
return def;
|
return def;
|
||||||
@@ -3620,12 +3620,8 @@ merge(Compressor.prototype, {
|
|||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
function in_delete(parent) {
|
function is_atomic(lhs, self) {
|
||||||
return parent instanceof AST_UnaryPrefix && parent.operator == "delete";
|
return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
|
||||||
}
|
|
||||||
|
|
||||||
function is_atomic(parent, self) {
|
|
||||||
return parent.expression instanceof AST_SymbolRef || parent.expression.TYPE === self.TYPE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OPT(AST_Undefined, function(self, compressor){
|
OPT(AST_Undefined, function(self, compressor){
|
||||||
@@ -3641,8 +3637,8 @@ merge(Compressor.prototype, {
|
|||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var parent = compressor.parent();
|
var lhs = is_lhs(compressor.self(), compressor.parent());
|
||||||
if (in_delete(parent) && is_atomic(parent, self)) return self;
|
if (lhs && is_atomic(lhs, self)) return self;
|
||||||
return make_node(AST_UnaryPrefix, self, {
|
return make_node(AST_UnaryPrefix, self, {
|
||||||
operator: "void",
|
operator: "void",
|
||||||
expression: make_node(AST_Number, self, {
|
expression: make_node(AST_Number, self, {
|
||||||
@@ -3652,11 +3648,10 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Infinity, function(self, compressor){
|
OPT(AST_Infinity, function(self, compressor){
|
||||||
var parent = compressor.parent();
|
var lhs = is_lhs(compressor.self(), compressor.parent());
|
||||||
var del = in_delete(parent);
|
if (lhs && is_atomic(lhs, self)) return self;
|
||||||
if (del && is_atomic(parent, self)) return self;
|
|
||||||
if (compressor.option("keep_infinity")
|
if (compressor.option("keep_infinity")
|
||||||
&& !(del && !is_atomic(parent, self))
|
&& !(lhs && !is_atomic(lhs, self))
|
||||||
&& !find_variable(compressor, "Infinity"))
|
&& !find_variable(compressor, "Infinity"))
|
||||||
return self;
|
return self;
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
@@ -3671,8 +3666,8 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_NaN, function(self, compressor){
|
OPT(AST_NaN, function(self, compressor){
|
||||||
var parent = compressor.parent();
|
var lhs = is_lhs(compressor.self(), compressor.parent());
|
||||||
if (in_delete(parent) && !is_atomic(parent, self)
|
if (lhs && !is_atomic(lhs, self)
|
||||||
|| find_variable(compressor, "NaN")) {
|
|| find_variable(compressor, "NaN")) {
|
||||||
return make_node(AST_Binary, self, {
|
return make_node(AST_Binary, self, {
|
||||||
operator: "/",
|
operator: "/",
|
||||||
|
|||||||
@@ -957,3 +957,35 @@ delete_binary_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
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