From: Alex Lam S.L Date: Sat, 28 Dec 2019 20:26:15 +0000 (+0000) Subject: enhance `evaluate` (#3649) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=d9cd3d33c8f2b769da922d355373d466f8b30704;p=UglifyJS.git enhance `evaluate` (#3649) --- diff --git a/bin/uglifyjs b/bin/uglifyjs index ace94e7e..dc9baf81 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -59,7 +59,7 @@ if (program.configFile) { if (options.mangle && options.mangle.properties && options.mangle.properties.regex) { options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, { expression: true - }).getValue(); + }).value; } } if (!program.output && program.sourceMap && program.sourceMap.url != "inline") { @@ -370,7 +370,7 @@ function parse_js(flag) { if (!(node instanceof UglifyJS.AST_Sequence)) throw node; function to_string(value) { - return value instanceof UglifyJS.AST_Constant ? value.getValue() : value.print_to_string({ + return value instanceof UglifyJS.AST_Constant ? value.value : value.print_to_string({ quote_keys: true }); } diff --git a/lib/ast.js b/lib/ast.js index b1704915..30885905 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -618,7 +618,7 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", { getProperty: function() { var p = this.property; if (p instanceof AST_Constant) { - return p.getValue(); + return p.value; } if (p instanceof AST_UnaryPrefix && p.operator == "void" @@ -824,9 +824,6 @@ var AST_This = DEFNODE("This", null, { var AST_Constant = DEFNODE("Constant", null, { $documentation: "Base class for all constants", - getValue: function() { - return this.value; - } }); var AST_String = DEFNODE("String", "value quote", { diff --git a/lib/compress.js b/lib/compress.js index e277e9a1..77f5d47c 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3014,7 +3014,7 @@ merge(Compressor.prototype, { def(AST_Lambda, return_this); def(AST_Node, return_this); def(AST_Constant, function() { - return this.getValue(); + return this.value; }); def(AST_Function, function(compressor) { if (compressor.option("unsafe")) { @@ -4877,7 +4877,7 @@ merge(Compressor.prototype, { var sym = condition.right.expression; if (!is_undeclared_ref(sym)) return; var body; - var undef = condition.left.getValue() == "undefined"; + var undef = condition.left.value == "undefined"; switch (condition.operator) { case "==": body = undef ? alternative : consequent; @@ -5313,7 +5313,7 @@ merge(Compressor.prototype, { if (self.args.length == 1) { var first = self.args[0]; if (first instanceof AST_Number) try { - var length = first.getValue(); + var length = first.value; if (length > 6) break; var elements = Array(length); for (var i = 0; i < length; i++) elements[i] = make_node(AST_Hole, self); @@ -6071,7 +6071,7 @@ merge(Compressor.prototype, { // "undefined" == typeof x => undefined === x else if (compressor.option("typeofs") && self.left instanceof AST_String - && self.left.getValue() == "undefined" + && self.left.value == "undefined" && self.right instanceof AST_UnaryPrefix && self.right.operator == "typeof") { var expr = self.right.expression; @@ -6143,7 +6143,7 @@ merge(Compressor.prototype, { } break; case "==": - if (self.left instanceof AST_String && self.left.getValue() == "" && self.right.is_string(compressor)) { + if (self.left instanceof AST_String && self.left.value == "" && self.right.is_string(compressor)) { return make_node(AST_UnaryPrefix, self, { operator: "!", expression: self.right @@ -6151,7 +6151,7 @@ merge(Compressor.prototype, { } break; case "!=": - if (self.left instanceof AST_String && self.left.getValue() == "" && self.right.is_string(compressor)) { + if (self.left instanceof AST_String && self.left.value == "" && self.right.is_string(compressor)) { return self.right.optimize(compressor); } break; @@ -6172,19 +6172,19 @@ merge(Compressor.prototype, { } if (self.operator == "+") { if (self.right instanceof AST_String - && self.right.getValue() == "" + && self.right.value == "" && self.left.is_string(compressor)) { return self.left.optimize(compressor); } if (self.left instanceof AST_String - && self.left.getValue() == "" + && self.left.value == "" && self.right.is_string(compressor)) { return self.right.optimize(compressor); } if (self.left instanceof AST_Binary && self.left.operator == "+" && self.left.left instanceof AST_String - && self.left.left.getValue() == "" + && self.left.left.value == "" && self.right.is_string(compressor)) { self.left = self.left.right; return self.optimize(compressor); @@ -6270,7 +6270,7 @@ merge(Compressor.prototype, { self = make_node(AST_Binary, self, { operator: "+", left: make_node(AST_String, self.left, { - value: "" + self.left.getValue() + self.right.left.getValue(), + value: "" + self.left.value + self.right.left.value, start: self.left.start, end: self.right.left.end }), @@ -6287,7 +6287,7 @@ merge(Compressor.prototype, { operator: "+", left: self.left.left, right: make_node(AST_String, self.right, { - value: "" + self.left.right.getValue() + self.right.getValue(), + value: "" + self.left.right.value + self.right.value, start: self.left.right.start, end: self.right.end }) @@ -6308,7 +6308,7 @@ merge(Compressor.prototype, { operator: "+", left: self.left.left, right: make_node(AST_String, self.left.right, { - value: "" + self.left.right.getValue() + self.right.left.getValue(), + value: "" + self.left.right.value + self.right.left.value, start: self.left.right.start, end: self.right.left.end }) @@ -6391,8 +6391,8 @@ merge(Compressor.prototype, { // a + +b => +b + a if (self.operator != "-" && self.operator != "/" - && self.left.is_number(compressor) - && self.right.is_number(compressor) + && (self.left.is_boolean(compressor) || self.left.is_number(compressor)) + && (self.right.is_boolean(compressor) || self.right.is_number(compressor)) && reversible() && !(self.left instanceof AST_Binary && self.left.operator != self.operator @@ -6455,6 +6455,43 @@ merge(Compressor.prototype, { } break; } + if (self.left instanceof AST_Number && !self.right.is_constant()) switch (self.operator) { + // 0 + n => n + case "+": + if (self.left.value == 0) { + if (self.right.is_number(compressor)) return self.right; + if (self.right.is_boolean(compressor)) return make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.right + }).optimize(compressor); + } + break; + // 0 - n => -n + case "-": + if (self.left.value == 0) return make_node(AST_UnaryPrefix, self, { + operator: "-", + expression: self.right + }).optimize(compressor); + break; + // 1 * n => n + case "*": + if (self.left.value == 1) { + return self.right.is_number(compressor) ? self.right : make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.right + }).optimize(compressor); + } + break; + } + // n - 0 => n + // n / 1 => n + if (self.right instanceof AST_Number && !self.left.is_constant() && self.right.value == { + "-": 0, + "/": 1, + }[self.operator]) return self.left.is_number(compressor) ? self.left : make_node(AST_UnaryPrefix, self, { + operator: "+", + expression: self.left + }).optimize(compressor); } if (compressor.option("typeofs")) switch (self.operator) { case "&&": @@ -6470,7 +6507,7 @@ merge(Compressor.prototype, { && indexRight && (self.operator == "==" || self.operator == "!=") && self.left instanceof AST_Number - && self.left.getValue() == 0) { + && self.left.value == 0) { return (self.operator == "==" ? make_node(AST_UnaryPrefix, self, { operator: "!", expression: self.right @@ -6573,19 +6610,19 @@ merge(Compressor.prototype, { switch (self.operator) { case "<=": // 0 <= array.indexOf(string) => !!~array.indexOf(string) - return indexRight && self.left instanceof AST_Number && self.left.getValue() == 0; + return indexRight && self.left instanceof AST_Number && self.left.value == 0; case "<": // array.indexOf(string) < 0 => !~array.indexOf(string) - if (indexLeft && self.right instanceof AST_Number && self.right.getValue() == 0) return true; + if (indexLeft && self.right instanceof AST_Number && self.right.value == 0) return true; // -1 < array.indexOf(string) => !!~array.indexOf(string) case "==": case "!=": // -1 == array.indexOf(string) => !~array.indexOf(string) // -1 != array.indexOf(string) => !!~array.indexOf(string) if (!indexRight) return false; - return self.left instanceof AST_Number && self.left.getValue() == -1 + return self.left instanceof AST_Number && self.left.value == -1 || self.left instanceof AST_UnaryPrefix && self.left.operator == "-" - && self.left.expression instanceof AST_Number && self.left.expression.getValue() == 1; + && self.left.expression instanceof AST_Number && self.left.expression.value == 1; } } }); @@ -6906,7 +6943,7 @@ merge(Compressor.prototype, { if ((self.operator == "-=" || self.operator == "+=" && (self.left.is_boolean(compressor) || self.left.is_number(compressor))) && self.right instanceof AST_Number - && self.right.getValue() === 1) { + && self.right.value == 1) { var op = self.operator.slice(0, -1); return make_node(AST_UnaryPrefix, self, { operator: op + op, @@ -7149,22 +7186,22 @@ merge(Compressor.prototype, { return node instanceof AST_True || in_bool && node instanceof AST_Constant - && node.getValue() + && node.value || (node instanceof AST_UnaryPrefix && node.operator == "!" && node.expression instanceof AST_Constant - && !node.expression.getValue()); + && !node.expression.value); } // AST_False or !1 function is_false(node) { return node instanceof AST_False || in_bool && node instanceof AST_Constant - && !node.getValue() + && !node.value || (node instanceof AST_UnaryPrefix && node.operator == "!" && node.expression instanceof AST_Constant - && node.expression.getValue()); + && node.expression.value); } function arg_diff() { @@ -7272,7 +7309,7 @@ merge(Compressor.prototype, { && is_arguments(def = expr.definition()) && prop instanceof AST_Number && (fn = expr.scope) === find_lambda()) { - var index = prop.getValue(); + var index = prop.value; if (parent instanceof AST_UnaryPrefix && parent.operator == "delete") { if (!def.deleted) def.deleted = []; def.deleted[index] = true; @@ -7318,7 +7355,7 @@ merge(Compressor.prototype, { } if (compressor.option("properties") && compressor.option("side_effects") && prop instanceof AST_Number && expr instanceof AST_Array) { - var index = prop.getValue(); + var index = prop.value; var elements = expr.elements; var retValue = elements[index]; if (safe_to_flatten(retValue, compressor)) { diff --git a/lib/output.js b/lib/output.js index 38b4f8bc..a63671c6 100644 --- a/lib/output.js +++ b/lib/output.js @@ -782,7 +782,7 @@ function OutputStream(options) { PARENS(AST_Number, function(output) { var p = output.parent(); if (p instanceof AST_PropAccess && p.expression === this) { - var value = this.getValue(); + var value = this.value; if (value < 0 || /^0/.test(make_num(value))) { return true; } @@ -1212,7 +1212,7 @@ function OutputStream(options) { output.print_string(prop); output.print("]"); } else { - if (expr instanceof AST_Number && expr.getValue() >= 0) { + if (expr instanceof AST_Number && expr.value >= 0) { if (!/[xa-f.)]/i.test(output.last())) { output.print("."); } @@ -1336,21 +1336,21 @@ function OutputStream(options) { output.print("this"); }); DEFPRINT(AST_Constant, function(self, output) { - output.print(self.getValue()); + output.print(self.value); }); DEFPRINT(AST_String, function(self, output) { - output.print_string(self.getValue(), self.quote); + output.print_string(self.value, self.quote); }); DEFPRINT(AST_Number, function(self, output) { if (use_asm && self.start && self.start.raw != null) { output.print(self.start.raw); } else { - output.print(make_num(self.getValue())); + output.print(make_num(self.value)); } }); DEFPRINT(AST_RegExp, function(self, output) { - var regexp = self.getValue(); + var regexp = self.value; var str = regexp.toString(); if (regexp.raw_source) { str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/")); diff --git a/test/compress/hoist_props.js b/test/compress/hoist_props.js index 0d8e771a..c647ccc1 100644 --- a/test/compress/hoist_props.js +++ b/test/compress/hoist_props.js @@ -664,7 +664,7 @@ issue_2519: { } expect: { function testFunc() { - return 1 * ((6 + 5) / 2); + return +((6 + 5) / 2); } console.log(testFunc()); } diff --git a/test/compress/numbers.js b/test/compress/numbers.js index 673ce23a..c432a435 100644 --- a/test/compress/numbers.js +++ b/test/compress/numbers.js @@ -91,7 +91,7 @@ evaluate_1: { expect: { console.log( x + 1 + 2, - 1 * x * 2, + 2 * x, +x + 1 + 2, 1 + x + 2 + 3, 3 | x, @@ -173,7 +173,7 @@ evaluate_2: { var x = "42", y = null; [ x + 1 + 2, - 1 * x * 2, + 2 * x, +x + 1 + 2, 1 + x + 2 + 3, 3 | x, @@ -979,3 +979,81 @@ unsafe_math_swap_constant: { } expect_stdout: "6 6 7 6 6 8 9 10" } + +identity_1: { + options = { + evaluate: true, + } + input: { + 0 + a; + a + 0; + 0 - a; + a - 0; + 1 * a; + a * 1; + 1 / a; + a / 1; + } + expect: { + 0 + a; + a + 0; + -a; + +a; + +a; + +a; + 1 / a; + +a; + } +} + +identity_2: { + options = { + evaluate: true, + } + input: { + 0 + !a; + !a + 0; + 0 - !a; + !a - 0; + 1 * !a; + !a * 1; + 1 / !a; + !a / 1; + } + expect: { + +!a; + +!a; + -!a; + +!a; + +!a; + +!a; + 1 / !a; + +!a; + } +} + +identity_3: { + options = { + evaluate: true, + } + input: { + 0 + --a; + --a + 0; + 0 - --a; + --a - 0; + 1 * --a; + --a * 1; + 1 / --a; + --a / 1; + } + expect: { + --a; + --a; + - --a; + --a; + --a; + --a; + 1 / --a; + --a; + } +}