aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2017-03-09 19:11:05 +0800
committerGitHub <noreply@github.com>2017-03-09 19:11:05 +0800
commitb633706ce42576b7e2aa85a96c5691bde87e71ac (patch)
tree524e6ab7980d86f0837c188cdb35fe8aa77b7487 /lib
parente9920f7ca162ce062cc481b876be293d7324a714 (diff)
downloadtracifyjs-b633706ce42576b7e2aa85a96c5691bde87e71ac.tar.gz
tracifyjs-b633706ce42576b7e2aa85a96c5691bde87e71ac.zip
fix & improve function argument compression (#1584)
- one-use function call => IIFE should take `eval()` & `arguments` into account - if unused parameter cannot be eliminated, replace it with `0` fixes #1583
Diffstat (limited to 'lib')
-rw-r--r--lib/compress.js46
1 files changed, 33 insertions, 13 deletions
diff --git a/lib/compress.js b/lib/compress.js
index f6b76ec2..3964636f 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -281,6 +281,9 @@ merge(Compressor.prototype, {
if (node instanceof AST_Function
&& (iife = tw.parent()) instanceof AST_Call
&& iife.expression === node) {
+ // Virtually turn IIFE parameters into variable definitions:
+ // (function(a,b) {...})(c,d) => (function() {var a=c,b=d; ...})()
+ // So existing transformation rules can work on them.
node.argnames.forEach(function(arg, i) {
var d = arg.definition();
d.fixed = iife.args[i] || make_node(AST_Undefined, iife);
@@ -1810,10 +1813,12 @@ merge(Compressor.prototype, {
node.name = null;
}
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
- if (!compressor.option("keep_fargs")) {
- for (var a = node.argnames, i = a.length; --i >= 0;) {
- var sym = a[i];
- if (!(sym.definition().id in in_use_ids)) {
+ var trim = !compressor.option("keep_fargs");
+ for (var a = node.argnames, i = a.length; --i >= 0;) {
+ var sym = a[i];
+ if (!(sym.definition().id in in_use_ids)) {
+ sym.__unused = true;
+ if (trim) {
a.pop();
compressor.warn("Dropping unused function argument {name} [{file}:{line},{col}]", {
name : sym.name,
@@ -1822,7 +1827,9 @@ merge(Compressor.prototype, {
col : sym.start.col
});
}
- else break;
+ }
+ else {
+ trim = false;
}
}
}
@@ -2609,6 +2616,9 @@ merge(Compressor.prototype, {
exp = def.fixed;
if (compressor.option("unused")
&& def.references.length == 1
+ && !(def.scope.uses_arguments
+ && def.orig[0] instanceof AST_SymbolFunarg)
+ && !def.scope.uses_eval
&& compressor.find_parent(AST_Scope) === def.scope) {
self.expression = exp;
}
@@ -2617,16 +2627,26 @@ merge(Compressor.prototype, {
if (compressor.option("unused")
&& exp instanceof AST_Function
&& !exp.uses_arguments
- && !exp.uses_eval
- && self.args.length > exp.argnames.length) {
- var end = exp.argnames.length;
- for (var i = end, len = self.args.length; i < len; i++) {
- var node = self.args[i].drop_side_effect_free(compressor);
- if (node) {
- self.args[end++] = node;
+ && !exp.uses_eval) {
+ var pos = 0, last = 0;
+ for (var i = 0, len = self.args.length; i < len; i++) {
+ var trim = i >= exp.argnames.length;
+ if (trim || exp.argnames[i].__unused) {
+ var node = self.args[i].drop_side_effect_free(compressor);
+ if (node) {
+ self.args[pos++] = node;
+ } else if (!trim) {
+ self.args[pos++] = make_node(AST_Number, self.args[i], {
+ value: 0
+ });
+ continue;
+ }
+ } else {
+ self.args[pos++] = self.args[i];
}
+ last = pos;
}
- self.args.length = end;
+ self.args.length = last;
}
if (compressor.option("unsafe")) {
if (exp instanceof AST_SymbolRef && exp.undeclared()) {