fix LHS cases for NaN & friends (#1804)

`Infinity = beyond` should not become `1/0 = beyond`
This commit is contained in:
Alex Lam S.L
2017-04-09 03:18:14 +08:00
committed by GitHub
parent 9a978843f5
commit d6fbc365e2
2 changed files with 47 additions and 20 deletions

View File

@@ -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: "/",

View File

@@ -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--;",
"}",
]
}