From: Alex Lam S.L Date: Sat, 8 Apr 2017 19:18:14 +0000 (+0800) Subject: fix LHS cases for NaN & friends (#1804) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=d6fbc365e2f00eaaba0f1dd19e81037a64976def;p=UglifyJS.git fix LHS cases for NaN & friends (#1804) `Infinity = beyond` should not become `1/0 = beyond` --- diff --git a/lib/compress.js b/lib/compress.js index 5b405ec1..1d9258cf 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -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: "/", diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js index 3c16e201..611acf0d 100644 --- a/test/compress/evaluate.js +++ b/test/compress/evaluate.js @@ -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--;", + "}", + ] +}