enhance evaluate (#3649)

This commit is contained in:
Alex Lam S.L
2019-12-28 20:26:15 +00:00
committed by GitHub
parent 22b47cdd63
commit d9cd3d33c8
6 changed files with 153 additions and 41 deletions

View File

@@ -59,7 +59,7 @@ if (program.configFile) {
if (options.mangle && options.mangle.properties && options.mangle.properties.regex) { if (options.mangle && options.mangle.properties && options.mangle.properties.regex) {
options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, { options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, {
expression: true expression: true
}).getValue(); }).value;
} }
} }
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") { 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; if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
function to_string(value) { 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 quote_keys: true
}); });
} }

View File

@@ -618,7 +618,7 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
getProperty: function() { getProperty: function() {
var p = this.property; var p = this.property;
if (p instanceof AST_Constant) { if (p instanceof AST_Constant) {
return p.getValue(); return p.value;
} }
if (p instanceof AST_UnaryPrefix if (p instanceof AST_UnaryPrefix
&& p.operator == "void" && p.operator == "void"
@@ -824,9 +824,6 @@ var AST_This = DEFNODE("This", null, {
var AST_Constant = DEFNODE("Constant", null, { var AST_Constant = DEFNODE("Constant", null, {
$documentation: "Base class for all constants", $documentation: "Base class for all constants",
getValue: function() {
return this.value;
}
}); });
var AST_String = DEFNODE("String", "value quote", { var AST_String = DEFNODE("String", "value quote", {

View File

@@ -3014,7 +3014,7 @@ merge(Compressor.prototype, {
def(AST_Lambda, return_this); def(AST_Lambda, return_this);
def(AST_Node, return_this); def(AST_Node, return_this);
def(AST_Constant, function() { def(AST_Constant, function() {
return this.getValue(); return this.value;
}); });
def(AST_Function, function(compressor) { def(AST_Function, function(compressor) {
if (compressor.option("unsafe")) { if (compressor.option("unsafe")) {
@@ -4877,7 +4877,7 @@ merge(Compressor.prototype, {
var sym = condition.right.expression; var sym = condition.right.expression;
if (!is_undeclared_ref(sym)) return; if (!is_undeclared_ref(sym)) return;
var body; var body;
var undef = condition.left.getValue() == "undefined"; var undef = condition.left.value == "undefined";
switch (condition.operator) { switch (condition.operator) {
case "==": case "==":
body = undef ? alternative : consequent; body = undef ? alternative : consequent;
@@ -5313,7 +5313,7 @@ merge(Compressor.prototype, {
if (self.args.length == 1) { if (self.args.length == 1) {
var first = self.args[0]; var first = self.args[0];
if (first instanceof AST_Number) try { if (first instanceof AST_Number) try {
var length = first.getValue(); var length = first.value;
if (length > 6) break; if (length > 6) break;
var elements = Array(length); var elements = Array(length);
for (var i = 0; i < length; i++) elements[i] = make_node(AST_Hole, self); 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 // "undefined" == typeof x => undefined === x
else if (compressor.option("typeofs") else if (compressor.option("typeofs")
&& self.left instanceof AST_String && self.left instanceof AST_String
&& self.left.getValue() == "undefined" && self.left.value == "undefined"
&& self.right instanceof AST_UnaryPrefix && self.right instanceof AST_UnaryPrefix
&& self.right.operator == "typeof") { && self.right.operator == "typeof") {
var expr = self.right.expression; var expr = self.right.expression;
@@ -6143,7 +6143,7 @@ merge(Compressor.prototype, {
} }
break; break;
case "==": 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, { return make_node(AST_UnaryPrefix, self, {
operator: "!", operator: "!",
expression: self.right expression: self.right
@@ -6151,7 +6151,7 @@ merge(Compressor.prototype, {
} }
break; break;
case "!=": 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); return self.right.optimize(compressor);
} }
break; break;
@@ -6172,19 +6172,19 @@ merge(Compressor.prototype, {
} }
if (self.operator == "+") { if (self.operator == "+") {
if (self.right instanceof AST_String if (self.right instanceof AST_String
&& self.right.getValue() == "" && self.right.value == ""
&& self.left.is_string(compressor)) { && self.left.is_string(compressor)) {
return self.left.optimize(compressor); return self.left.optimize(compressor);
} }
if (self.left instanceof AST_String if (self.left instanceof AST_String
&& self.left.getValue() == "" && self.left.value == ""
&& self.right.is_string(compressor)) { && self.right.is_string(compressor)) {
return self.right.optimize(compressor); return self.right.optimize(compressor);
} }
if (self.left instanceof AST_Binary if (self.left instanceof AST_Binary
&& self.left.operator == "+" && self.left.operator == "+"
&& self.left.left instanceof AST_String && self.left.left instanceof AST_String
&& self.left.left.getValue() == "" && self.left.left.value == ""
&& self.right.is_string(compressor)) { && self.right.is_string(compressor)) {
self.left = self.left.right; self.left = self.left.right;
return self.optimize(compressor); return self.optimize(compressor);
@@ -6270,7 +6270,7 @@ merge(Compressor.prototype, {
self = make_node(AST_Binary, self, { self = make_node(AST_Binary, self, {
operator: "+", operator: "+",
left: make_node(AST_String, self.left, { 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, start: self.left.start,
end: self.right.left.end end: self.right.left.end
}), }),
@@ -6287,7 +6287,7 @@ merge(Compressor.prototype, {
operator: "+", operator: "+",
left: self.left.left, left: self.left.left,
right: make_node(AST_String, self.right, { 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, start: self.left.right.start,
end: self.right.end end: self.right.end
}) })
@@ -6308,7 +6308,7 @@ merge(Compressor.prototype, {
operator: "+", operator: "+",
left: self.left.left, left: self.left.left,
right: make_node(AST_String, self.left.right, { 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, start: self.left.right.start,
end: self.right.left.end end: self.right.left.end
}) })
@@ -6391,8 +6391,8 @@ merge(Compressor.prototype, {
// a + +b => +b + a // a + +b => +b + a
if (self.operator != "-" if (self.operator != "-"
&& self.operator != "/" && self.operator != "/"
&& self.left.is_number(compressor) && (self.left.is_boolean(compressor) || self.left.is_number(compressor))
&& self.right.is_number(compressor) && (self.right.is_boolean(compressor) || self.right.is_number(compressor))
&& reversible() && reversible()
&& !(self.left instanceof AST_Binary && !(self.left instanceof AST_Binary
&& self.left.operator != self.operator && self.left.operator != self.operator
@@ -6455,6 +6455,43 @@ merge(Compressor.prototype, {
} }
break; 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) { if (compressor.option("typeofs")) switch (self.operator) {
case "&&": case "&&":
@@ -6470,7 +6507,7 @@ merge(Compressor.prototype, {
&& indexRight && indexRight
&& (self.operator == "==" || self.operator == "!=") && (self.operator == "==" || self.operator == "!=")
&& self.left instanceof AST_Number && self.left instanceof AST_Number
&& self.left.getValue() == 0) { && self.left.value == 0) {
return (self.operator == "==" ? make_node(AST_UnaryPrefix, self, { return (self.operator == "==" ? make_node(AST_UnaryPrefix, self, {
operator: "!", operator: "!",
expression: self.right expression: self.right
@@ -6573,19 +6610,19 @@ merge(Compressor.prototype, {
switch (self.operator) { switch (self.operator) {
case "<=": case "<=":
// 0 <= array.indexOf(string) => !!~array.indexOf(string) // 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 "<": case "<":
// array.indexOf(string) < 0 => !~array.indexOf(string) // 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) // -1 < array.indexOf(string) => !!~array.indexOf(string)
case "==": case "==":
case "!=": case "!=":
// -1 == array.indexOf(string) => !~array.indexOf(string) // -1 == array.indexOf(string) => !~array.indexOf(string)
// -1 != array.indexOf(string) => !!~array.indexOf(string) // -1 != array.indexOf(string) => !!~array.indexOf(string)
if (!indexRight) return false; 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 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 == "+=" if ((self.operator == "-=" || self.operator == "+="
&& (self.left.is_boolean(compressor) || self.left.is_number(compressor))) && (self.left.is_boolean(compressor) || self.left.is_number(compressor)))
&& self.right instanceof AST_Number && self.right instanceof AST_Number
&& self.right.getValue() === 1) { && self.right.value == 1) {
var op = self.operator.slice(0, -1); var op = self.operator.slice(0, -1);
return make_node(AST_UnaryPrefix, self, { return make_node(AST_UnaryPrefix, self, {
operator: op + op, operator: op + op,
@@ -7149,22 +7186,22 @@ merge(Compressor.prototype, {
return node instanceof AST_True return node instanceof AST_True
|| in_bool || in_bool
&& node instanceof AST_Constant && node instanceof AST_Constant
&& node.getValue() && node.value
|| (node instanceof AST_UnaryPrefix || (node instanceof AST_UnaryPrefix
&& node.operator == "!" && node.operator == "!"
&& node.expression instanceof AST_Constant && node.expression instanceof AST_Constant
&& !node.expression.getValue()); && !node.expression.value);
} }
// AST_False or !1 // AST_False or !1
function is_false(node) { function is_false(node) {
return node instanceof AST_False return node instanceof AST_False
|| in_bool || in_bool
&& node instanceof AST_Constant && node instanceof AST_Constant
&& !node.getValue() && !node.value
|| (node instanceof AST_UnaryPrefix || (node instanceof AST_UnaryPrefix
&& node.operator == "!" && node.operator == "!"
&& node.expression instanceof AST_Constant && node.expression instanceof AST_Constant
&& node.expression.getValue()); && node.expression.value);
} }
function arg_diff() { function arg_diff() {
@@ -7272,7 +7309,7 @@ merge(Compressor.prototype, {
&& is_arguments(def = expr.definition()) && is_arguments(def = expr.definition())
&& prop instanceof AST_Number && prop instanceof AST_Number
&& (fn = expr.scope) === find_lambda()) { && (fn = expr.scope) === find_lambda()) {
var index = prop.getValue(); var index = prop.value;
if (parent instanceof AST_UnaryPrefix && parent.operator == "delete") { if (parent instanceof AST_UnaryPrefix && parent.operator == "delete") {
if (!def.deleted) def.deleted = []; if (!def.deleted) def.deleted = [];
def.deleted[index] = true; def.deleted[index] = true;
@@ -7318,7 +7355,7 @@ merge(Compressor.prototype, {
} }
if (compressor.option("properties") && compressor.option("side_effects") if (compressor.option("properties") && compressor.option("side_effects")
&& prop instanceof AST_Number && expr instanceof AST_Array) { && prop instanceof AST_Number && expr instanceof AST_Array) {
var index = prop.getValue(); var index = prop.value;
var elements = expr.elements; var elements = expr.elements;
var retValue = elements[index]; var retValue = elements[index];
if (safe_to_flatten(retValue, compressor)) { if (safe_to_flatten(retValue, compressor)) {

View File

@@ -782,7 +782,7 @@ function OutputStream(options) {
PARENS(AST_Number, function(output) { PARENS(AST_Number, function(output) {
var p = output.parent(); var p = output.parent();
if (p instanceof AST_PropAccess && p.expression === this) { if (p instanceof AST_PropAccess && p.expression === this) {
var value = this.getValue(); var value = this.value;
if (value < 0 || /^0/.test(make_num(value))) { if (value < 0 || /^0/.test(make_num(value))) {
return true; return true;
} }
@@ -1212,7 +1212,7 @@ function OutputStream(options) {
output.print_string(prop); output.print_string(prop);
output.print("]"); output.print("]");
} else { } else {
if (expr instanceof AST_Number && expr.getValue() >= 0) { if (expr instanceof AST_Number && expr.value >= 0) {
if (!/[xa-f.)]/i.test(output.last())) { if (!/[xa-f.)]/i.test(output.last())) {
output.print("."); output.print(".");
} }
@@ -1336,21 +1336,21 @@ function OutputStream(options) {
output.print("this"); output.print("this");
}); });
DEFPRINT(AST_Constant, function(self, output) { DEFPRINT(AST_Constant, function(self, output) {
output.print(self.getValue()); output.print(self.value);
}); });
DEFPRINT(AST_String, function(self, output) { 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) { DEFPRINT(AST_Number, function(self, output) {
if (use_asm && self.start && self.start.raw != null) { if (use_asm && self.start && self.start.raw != null) {
output.print(self.start.raw); output.print(self.start.raw);
} else { } else {
output.print(make_num(self.getValue())); output.print(make_num(self.value));
} }
}); });
DEFPRINT(AST_RegExp, function(self, output) { DEFPRINT(AST_RegExp, function(self, output) {
var regexp = self.getValue(); var regexp = self.value;
var str = regexp.toString(); var str = regexp.toString();
if (regexp.raw_source) { if (regexp.raw_source) {
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/")); str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));

View File

@@ -664,7 +664,7 @@ issue_2519: {
} }
expect: { expect: {
function testFunc() { function testFunc() {
return 1 * ((6 + 5) / 2); return +((6 + 5) / 2);
} }
console.log(testFunc()); console.log(testFunc());
} }

View File

@@ -91,7 +91,7 @@ evaluate_1: {
expect: { expect: {
console.log( console.log(
x + 1 + 2, x + 1 + 2,
1 * x * 2, 2 * x,
+x + 1 + 2, +x + 1 + 2,
1 + x + 2 + 3, 1 + x + 2 + 3,
3 | x, 3 | x,
@@ -173,7 +173,7 @@ evaluate_2: {
var x = "42", y = null; var x = "42", y = null;
[ [
x + 1 + 2, x + 1 + 2,
1 * x * 2, 2 * x,
+x + 1 + 2, +x + 1 + 2,
1 + x + 2 + 3, 1 + x + 2 + 3,
3 | x, 3 | x,
@@ -979,3 +979,81 @@ unsafe_math_swap_constant: {
} }
expect_stdout: "6 6 7 6 6 8 9 10" 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;
}
}