terser
Advanced tools
Comparing version 5.27.2 to 5.28.0
# Changelog | ||
## v5.28.0 | ||
- Optimise redundant or shrinkable bitwise operations (`|`, `^`, `&`, `>>`, `<<`) | ||
- Evaluate some `BigInt` math operations | ||
## v5.27.2 | ||
@@ -4,0 +8,0 @@ - Recognise `this` as a reference to the surrounding class in `drop_unused`. Closes #1472 |
@@ -47,2 +47,3 @@ /*********************************************************************** | ||
AST_Arrow, | ||
AST_BigInt, | ||
AST_BlockStatement, | ||
@@ -128,2 +129,4 @@ AST_Call, | ||
}) : make_node(AST_Infinity, orig); | ||
case "bigint": | ||
return make_node(AST_BigInt, orig, { value: val.toString() }); | ||
case "boolean": | ||
@@ -130,0 +133,0 @@ return make_node(val ? AST_True : AST_False, orig); |
@@ -136,3 +136,10 @@ /*********************************************************************** | ||
def_eval(AST_BigInt, return_this); | ||
const supports_bigint = typeof BigInt === "function"; | ||
def_eval(AST_BigInt, function () { | ||
if (supports_bigint) { | ||
return BigInt(this.value); | ||
} else { | ||
return this; | ||
} | ||
}); | ||
@@ -261,3 +268,2 @@ def_eval(AST_RegExp, function (compressor) { | ||
return this; | ||
var result; | ||
@@ -274,2 +280,13 @@ if (left != null | ||
// Do not mix BigInt and Number; Don't use `>>>` on BigInt or `/ 0n` | ||
if ( | ||
(typeof left === "bigint") !== (typeof right === "bigint") | ||
|| typeof left === "bigint" | ||
&& (this.operator === ">>>" | ||
|| this.operator === "/" && Number(right) === 0) | ||
) { | ||
return this; | ||
} | ||
var result; | ||
switch (this.operator) { | ||
@@ -284,3 +301,3 @@ case "&&": result = left && right; break; | ||
case "*": result = left * right; break; | ||
case "**": result = Math.pow(left, right); break; | ||
case "**": result = left ** right; break; | ||
case "/": result = left / right; break; | ||
@@ -303,3 +320,3 @@ case "%": result = left % right; break; | ||
} | ||
if (isNaN(result) && compressor.find_parent(AST_With)) { | ||
if (typeof result === "number" && isNaN(result) && compressor.find_parent(AST_With)) { | ||
// leave original expression as is | ||
@@ -306,0 +323,0 @@ return this; |
@@ -136,2 +136,3 @@ /*********************************************************************** | ||
export const bitwise_binop = makePredicate("<<< >> << & | ^ ~"); | ||
export const lazy_op = makePredicate("&& || ??"); | ||
@@ -197,2 +198,20 @@ export const unary_side_effects = makePredicate("delete ++ --"); | ||
// methods to determine if an expression is a 32 bit integer (IE results from bitwise ops, or is an integer constant fitting in that size | ||
(function(def_is_32_bit_integer) { | ||
def_is_32_bit_integer(AST_Node, return_false); | ||
def_is_32_bit_integer(AST_Number, function() { | ||
return this.value === (this.value | 0); | ||
}); | ||
def_is_32_bit_integer(AST_UnaryPrefix, function() { | ||
return this.operator == "~" ? this.expression.is_number() | ||
: this.operator === "+" ? this.expression.is_32_bit_integer() | ||
: false; | ||
}); | ||
def_is_32_bit_integer(AST_Binary, function() { | ||
return bitwise_binop.has(this.operator); | ||
}); | ||
}(function (node, func) { | ||
node.DEFMETHOD("is_32_bit_integer", func); | ||
})); | ||
// methods to determine if an expression has a string result type | ||
@@ -812,2 +831,33 @@ (function(def_is_string) { | ||
(function (def_bitwise_negate) { | ||
function basic_negation(exp) { | ||
return make_node(AST_UnaryPrefix, exp, { | ||
operator: "~", | ||
expression: exp | ||
}); | ||
} | ||
def_bitwise_negate(AST_Node, function() { | ||
return basic_negation(this); | ||
}); | ||
def_bitwise_negate(AST_Number, function() { | ||
const neg = ~this.value; | ||
if (neg.toString().length > this.value.toString().length) { | ||
return basic_negation(this); | ||
} | ||
return make_node(AST_Number, this, { value: neg }); | ||
}); | ||
def_bitwise_negate(AST_UnaryPrefix, function(in_32_bit_context) { | ||
if (this.operator == "~" && (in_32_bit_context || this.expression.is_32_bit_integer())) { | ||
return this.expression; | ||
} else { | ||
return basic_negation(this); | ||
} | ||
}); | ||
})(function (node, func) { | ||
node.DEFMETHOD("bitwise_negate", func); | ||
}); | ||
// Is the callee of this function pure? | ||
@@ -814,0 +864,0 @@ var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError"); |
@@ -409,4 +409,4 @@ import { | ||
AST_ClassStaticBlock.prototype._size = function () { | ||
// "class{}" + semicolons | ||
return 7 + list_overhead(this.body); | ||
// "static{}" + semicolons | ||
return 8 + list_overhead(this.body); | ||
}; | ||
@@ -413,0 +413,0 @@ |
@@ -7,3 +7,3 @@ { | ||
"license": "BSD-2-Clause", | ||
"version": "5.27.2", | ||
"version": "5.28.0", | ||
"engines": { | ||
@@ -10,0 +10,0 @@ "node": ">=10" |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
2149717
61024