[Pkg-javascript-commits] [uglifyjs] 446/491: improve `unused` on built-in functions (#2817)
Jonas Smedegaard
dr at jones.dk
Wed Feb 14 19:52:03 UTC 2018
This is an automated email from the git hooks/post-receive script.
js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.
commit 3e7873217cad8b6f67839cb06d1e126ca231bc42
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Fri Jan 19 20:41:57 2018 +0800
improve `unused` on built-in functions (#2817)
---
lib/compress.js | 216 ++++++++++++++++++++++++++---------------
test/compress/collapse_vars.js | 23 +++++
test/compress/dead-code.js | 17 ++++
test/compress/evaluate.js | 36 +++++--
4 files changed, 205 insertions(+), 87 deletions(-)
diff --git a/lib/compress.js b/lib/compress.js
index 00593e8..5235a05 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -2113,6 +2113,95 @@ merge(Compressor.prototype, {
return (first_in_statement(compressor) ? best_of_statement : best_of_expression)(ast1, ast2);
}
+ function convert_to_predicate(obj) {
+ for (var key in obj) {
+ obj[key] = makePredicate(obj[key]);
+ }
+ }
+
+ var object_fns = [
+ "constructor",
+ "toString",
+ "valueOf",
+ ];
+ var native_fns = {
+ Array: [
+ "indexOf",
+ "join",
+ "lastIndexOf",
+ "slice",
+ ].concat(object_fns),
+ Boolean: object_fns,
+ Number: [
+ "toExponential",
+ "toFixed",
+ "toPrecision",
+ ].concat(object_fns),
+ Object: object_fns,
+ RegExp: [
+ "test",
+ ].concat(object_fns),
+ String: [
+ "charAt",
+ "charCodeAt",
+ "concat",
+ "indexOf",
+ "italics",
+ "lastIndexOf",
+ "match",
+ "replace",
+ "search",
+ "slice",
+ "split",
+ "substr",
+ "substring",
+ "trim",
+ ].concat(object_fns),
+ };
+ convert_to_predicate(native_fns);
+ var static_fns = {
+ Array: [
+ "isArray",
+ ],
+ Math: [
+ "abs",
+ "acos",
+ "asin",
+ "atan",
+ "ceil",
+ "cos",
+ "exp",
+ "floor",
+ "log",
+ "round",
+ "sin",
+ "sqrt",
+ "tan",
+ "atan2",
+ "pow",
+ "max",
+ "min",
+ ],
+ Number: [
+ "isFinite",
+ "isNaN",
+ ],
+ Object: [
+ "create",
+ "getOwnPropertyDescriptor",
+ "getOwnPropertyNames",
+ "getPrototypeOf",
+ "isExtensible",
+ "isFrozen",
+ "isSealed",
+ "keys",
+ ],
+ String: [
+ "fromCharCode",
+ ],
+ };
+ convert_to_predicate(static_fns);
+
// methods to evaluate a constant expression
(function(def){
// If the node has been successfully reduced to a constant,
@@ -2278,13 +2367,9 @@ merge(Compressor.prototype, {
Array: Array,
Math: Math,
Number: Number,
+ Object: Object,
String: String,
};
- function convert_to_predicate(obj) {
- for (var key in obj) {
- obj[key] = makePredicate(obj[key]);
- }
- }
var static_values = {
Math: [
"E",
@@ -2325,77 +2410,6 @@ merge(Compressor.prototype, {
}
return this;
});
- var object_fns = [
- "constructor",
- "toString",
- "valueOf",
- ];
- var native_fns = {
- Array: [
- "indexOf",
- "join",
- "lastIndexOf",
- "slice",
- ].concat(object_fns),
- Boolean: object_fns,
- Number: [
- "toExponential",
- "toFixed",
- "toPrecision",
- ].concat(object_fns),
- RegExp: [
- "test",
- ].concat(object_fns),
- String: [
- "charAt",
- "charCodeAt",
- "concat",
- "indexOf",
- "italics",
- "lastIndexOf",
- "match",
- "replace",
- "search",
- "slice",
- "split",
- "substr",
- "substring",
- "trim",
- ].concat(object_fns),
- };
- convert_to_predicate(native_fns);
- var static_fns = {
- Array: [
- "isArray",
- ],
- Math: [
- "abs",
- "acos",
- "asin",
- "atan",
- "ceil",
- "cos",
- "exp",
- "floor",
- "log",
- "round",
- "sin",
- "sqrt",
- "tan",
- "atan2",
- "pow",
- "max",
- "min"
- ],
- Number: [
- "isFinite",
- "isNaN",
- ],
- String: [
- "fromCharCode",
- ],
- };
- convert_to_predicate(static_fns);
def(AST_Call, function(compressor, depth) {
var exp = this.expression;
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
@@ -2420,7 +2434,16 @@ merge(Compressor.prototype, {
if (arg === value) return this;
args.push(value);
}
- return val[key].apply(val, args);
+ try {
+ return val[key].apply(val, args);
+ } catch (ex) {
+ compressor.warn("Error evaluating {code} [{file}:{line},{col}]", {
+ code: this.print_to_string(),
+ file: this.start.file,
+ line: this.start.line,
+ col: this.start.col
+ });
+ }
}
return this;
});
@@ -2511,9 +2534,34 @@ merge(Compressor.prototype, {
if (compressor.option("unsafe")) {
var expr = this.expression;
if (is_undeclared_ref(expr) && global_pure_fns(expr.name)) return true;
+ if (expr instanceof AST_Dot
+ && is_undeclared_ref(expr.expression)
+ && (static_fns[expr.expression.name] || return_false)(expr.property)) {
+ return true;
+ }
}
return this.pure || !compressor.pure_funcs(this);
});
+ AST_Node.DEFMETHOD("is_call_pure", return_false);
+ AST_Dot.DEFMETHOD("is_call_pure", function(compressor) {
+ if (!compressor.option("unsafe")) return;
+ var expr = this.expression;
+ var fns = return_false;
+ if (expr instanceof AST_Array) {
+ fns = native_fns.Array;
+ } else if (expr.is_boolean()) {
+ fns = native_fns.Boolean;
+ } else if (expr.is_number(compressor)) {
+ fns = native_fns.Number;
+ } else if (expr instanceof AST_RegExp) {
+ fns = native_fns.RegExp;
+ } else if (expr.is_string(compressor)) {
+ fns = native_fns.String;
+ } else if (!this.may_throw_on_access(compressor)) {
+ fns = native_fns.Object;
+ }
+ return fns(this.property);
+ });
// determine if expression has side effects
(function(def){
@@ -2534,8 +2582,12 @@ merge(Compressor.prototype, {
return any(this.body, compressor);
});
def(AST_Call, function(compressor){
- return !this.is_expr_pure(compressor)
- || any(this.args, compressor);
+ if (!this.is_expr_pure(compressor)
+ && (!this.expression.is_call_pure(compressor)
+ || this.expression.has_side_effects(compressor))) {
+ return true;
+ }
+ return any(this.args, compressor);
});
def(AST_Switch, function(compressor){
return this.expression.has_side_effects(compressor)
@@ -3365,6 +3417,12 @@ merge(Compressor.prototype, {
def(AST_This, return_null);
def(AST_Call, function(compressor, first_in_statement){
if (!this.is_expr_pure(compressor)) {
+ if (this.expression.is_call_pure(compressor)) {
+ var exprs = this.args.slice();
+ exprs.unshift(this.expression.expression);
+ exprs = trim(exprs, compressor, first_in_statement);
+ return exprs && make_sequence(this, exprs);
+ }
if (this.expression instanceof AST_Function
&& (!this.expression.name || !this.expression.name.definition().references.length)) {
var node = this.clone();
diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js
index 9597b67..970f822 100644
--- a/test/compress/collapse_vars.js
+++ b/test/compress/collapse_vars.js
@@ -4089,3 +4089,26 @@ cascade_forin: {
"2",
]
}
+
+unsafe_builtin: {
+ options = {
+ collapse_vars: true,
+ pure_getters: "strict",
+ unsafe: true,
+ unused: true,
+ }
+ input: {
+ function f(a) {
+ var b = Math.abs(a);
+ return Math.pow(b, 2);
+ }
+ console.log(f(-1), f(2));
+ }
+ expect: {
+ function f(a) {
+ return Math.pow(Math.abs(a), 2);
+ }
+ console.log(f(-1), f(2));
+ }
+ expect_stdout: "1 4"
+}
diff --git a/test/compress/dead-code.js b/test/compress/dead-code.js
index afc8c56..b66d5ac 100644
--- a/test/compress/dead-code.js
+++ b/test/compress/dead-code.js
@@ -862,3 +862,20 @@ issue_2749: {
}
expect_stdout: "PASS"
}
+
+unsafe_builtin: {
+ options = {
+ side_effects: true,
+ unsafe: true,
+ }
+ input: {
+ (!w).constructor(x);
+ Math.abs(y);
+ [ 1, 2, z ].valueOf();
+ }
+ expect: {
+ w, x;
+ y;
+ z;
+ }
+}
diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js
index 6106fce..d40880f 100644
--- a/test/compress/evaluate.js
+++ b/test/compress/evaluate.js
@@ -1194,6 +1194,9 @@ issue_2231_1: {
console.log(Object.keys(void 0));
}
expect_stdout: true
+ expect_warnings: [
+ "WARN: Error evaluating Object.keys(void 0) [test/compress/evaluate.js:1191,20]",
+ ]
}
issue_2231_2: {
@@ -1208,6 +1211,23 @@ issue_2231_2: {
console.log(Object.getOwnPropertyNames(null));
}
expect_stdout: true
+ expect_warnings: [
+ "WARN: Error evaluating Object.getOwnPropertyNames(null) [test/compress/evaluate.js:1208,20]",
+ ]
+}
+
+issue_2231_3: {
+ options = {
+ evaluate: true,
+ unsafe: true,
+ }
+ input: {
+ console.log(Object.keys({ foo: "bar" })[0]);
+ }
+ expect: {
+ console.log("foo");
+ }
+ expect_stdout: "foo"
}
self_comparison_1: {
@@ -1330,13 +1350,13 @@ issue_2535_3: {
}
expect_stdout: true
expect_warnings: [
- "WARN: Dropping side-effect-free && [test/compress/evaluate.js:1316,20]",
- "WARN: Dropping side-effect-free && [test/compress/evaluate.js:1317,20]",
- "WARN: Dropping side-effect-free && [test/compress/evaluate.js:1318,20]",
- "WARN: Condition left of && always false [test/compress/evaluate.js:1318,20]",
- "WARN: Dropping side-effect-free || [test/compress/evaluate.js:1319,20]",
- "WARN: Dropping side-effect-free || [test/compress/evaluate.js:1320,20]",
- "WARN: Dropping side-effect-free || [test/compress/evaluate.js:1321,20]",
- "WARN: Condition left of || always true [test/compress/evaluate.js:1321,20]",
+ "WARN: Dropping side-effect-free && [test/compress/evaluate.js:1336,20]",
+ "WARN: Dropping side-effect-free && [test/compress/evaluate.js:1337,20]",
+ "WARN: Dropping side-effect-free && [test/compress/evaluate.js:1338,20]",
+ "WARN: Condition left of && always false [test/compress/evaluate.js:1338,20]",
+ "WARN: Dropping side-effect-free || [test/compress/evaluate.js:1339,20]",
+ "WARN: Dropping side-effect-free || [test/compress/evaluate.js:1340,20]",
+ "WARN: Dropping side-effect-free || [test/compress/evaluate.js:1341,20]",
+ "WARN: Condition left of || always true [test/compress/evaluate.js:1341,20]",
]
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git
More information about the Pkg-javascript-commits
mailing list