enhance join_vars (#5739)
This commit is contained in:
@@ -487,7 +487,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return all(def.orig, function(sym) {
|
return all(def.orig, function(sym) {
|
||||||
if (sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet) {
|
if (sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet) {
|
||||||
if (sym instanceof AST_SymbolImport) return true;
|
if (sym instanceof AST_SymbolImport) return true;
|
||||||
return compressor && can_varify(compressor, sym);
|
return compressor && safe_from_tdz(compressor, sym);
|
||||||
}
|
}
|
||||||
return !(keep_lambda && sym instanceof AST_SymbolLambda);
|
return !(keep_lambda && sym instanceof AST_SymbolLambda);
|
||||||
});
|
});
|
||||||
@@ -525,10 +525,11 @@ Compressor.prototype.compress = function(node) {
|
|||||||
function reset_def(tw, compressor, def) {
|
function reset_def(tw, compressor, def) {
|
||||||
def.assignments = 0;
|
def.assignments = 0;
|
||||||
def.bool_return = 0;
|
def.bool_return = 0;
|
||||||
def.drop_return = 0;
|
|
||||||
def.cross_loop = false;
|
def.cross_loop = false;
|
||||||
def.direct_access = false;
|
def.direct_access = false;
|
||||||
|
def.drop_return = 0;
|
||||||
def.escaped = [];
|
def.escaped = [];
|
||||||
|
def.first_decl = null;
|
||||||
def.fixed = !def.const_redefs
|
def.fixed = !def.const_redefs
|
||||||
&& !def.scope.pinned()
|
&& !def.scope.pinned()
|
||||||
&& !compressor.exposed(def)
|
&& !compressor.exposed(def)
|
||||||
@@ -951,6 +952,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
|
|
||||||
function visit(node, fixed) {
|
function visit(node, fixed) {
|
||||||
var d = node.definition();
|
var d = node.definition();
|
||||||
|
if (!d.first_decl && d.references.length == 0) d.first_decl = node;
|
||||||
if (fixed && safe && d.fixed === undefined) {
|
if (fixed && safe && d.fixed === undefined) {
|
||||||
mark(tw, d);
|
mark(tw, d);
|
||||||
tw.loop_ids[d.id] = tw.in_loop;
|
tw.loop_ids[d.id] = tw.in_loop;
|
||||||
@@ -1371,10 +1373,18 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
def(AST_SymbolCatch, function() {
|
def(AST_SymbolCatch, function() {
|
||||||
this.definition().fixed = false;
|
var d = this.definition();
|
||||||
|
if (!d.first_decl && d.references.length == 0) d.first_decl = this;
|
||||||
|
d.fixed = false;
|
||||||
|
});
|
||||||
|
def(AST_SymbolDeclaration, function() {
|
||||||
|
var d = this.definition();
|
||||||
|
if (!d.first_decl && d.references.length == 0) d.first_decl = this;
|
||||||
});
|
});
|
||||||
def(AST_SymbolImport, function() {
|
def(AST_SymbolImport, function() {
|
||||||
this.definition().fixed = false;
|
var d = this.definition();
|
||||||
|
d.first_decl = this;
|
||||||
|
d.fixed = false;
|
||||||
});
|
});
|
||||||
def(AST_SymbolRef, function(tw, descend, compressor) {
|
def(AST_SymbolRef, function(tw, descend, compressor) {
|
||||||
var ref = this;
|
var ref = this;
|
||||||
@@ -1558,6 +1568,8 @@ Compressor.prototype.compress = function(node) {
|
|||||||
walk_defn();
|
walk_defn();
|
||||||
} else if (tw.parent() instanceof AST_Let) {
|
} else if (tw.parent() instanceof AST_Let) {
|
||||||
walk_defn();
|
walk_defn();
|
||||||
|
} else {
|
||||||
|
node.name.walk(tw);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -1566,6 +1578,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
return node.value || make_node(AST_Undefined, node);
|
return node.value || make_node(AST_Undefined, node);
|
||||||
}, function(name, fixed) {
|
}, function(name, fixed) {
|
||||||
var d = name.definition();
|
var d = name.definition();
|
||||||
|
if (!d.first_decl && d.references.length == 0) d.first_decl = name;
|
||||||
if (fixed && safe_to_assign(tw, d, true)) {
|
if (fixed && safe_to_assign(tw, d, true)) {
|
||||||
mark(tw, d);
|
mark(tw, d);
|
||||||
tw.loop_ids[d.id] = tw.in_loop;
|
tw.loop_ids[d.id] = tw.in_loop;
|
||||||
@@ -4249,7 +4262,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function join_consecutive_vars(statements) {
|
function join_consecutive_vars(statements) {
|
||||||
var changed = false, defs;
|
var changed = false, defs, prev_defs;
|
||||||
for (var i = 0, j = -1; i < statements.length; i++) {
|
for (var i = 0, j = -1; i < statements.length; i++) {
|
||||||
var stat = statements[i];
|
var stat = statements[i];
|
||||||
var prev = statements[j];
|
var prev = statements[j];
|
||||||
@@ -4257,6 +4270,14 @@ Compressor.prototype.compress = function(node) {
|
|||||||
if (prev && prev.TYPE == stat.TYPE) {
|
if (prev && prev.TYPE == stat.TYPE) {
|
||||||
prev.definitions = prev.definitions.concat(stat.definitions);
|
prev.definitions = prev.definitions.concat(stat.definitions);
|
||||||
changed = true;
|
changed = true;
|
||||||
|
} else if (stat && prev instanceof AST_Let && stat.can_letify(compressor)) {
|
||||||
|
prev.definitions = prev.definitions.concat(to_let(stat).definitions);
|
||||||
|
changed = true;
|
||||||
|
} else if (prev && stat instanceof AST_Let && prev.can_letify(compressor)) {
|
||||||
|
defs = prev_defs;
|
||||||
|
statements[j] = prev = to_let(prev);
|
||||||
|
prev.definitions = prev.definitions.concat(stat.definitions);
|
||||||
|
changed = true;
|
||||||
} else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) {
|
} else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) {
|
||||||
defs.definitions = defs.definitions.concat(stat.definitions);
|
defs.definitions = defs.definitions.concat(stat.definitions);
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -4271,6 +4292,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
} else {
|
} else {
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
prev_defs = defs;
|
||||||
statements[j] = defs = stat;
|
statements[j] = defs = stat;
|
||||||
} else {
|
} else {
|
||||||
statements[++j] = stat;
|
statements[++j] = stat;
|
||||||
@@ -4288,6 +4310,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
prev.definitions = prev.definitions.concat(stat.init.definitions);
|
prev.definitions = prev.definitions.concat(stat.init.definitions);
|
||||||
}
|
}
|
||||||
stat = stat.clone();
|
stat = stat.clone();
|
||||||
|
prev_defs = defs;
|
||||||
defs = stat.init = prev;
|
defs = stat.init = prev;
|
||||||
statements[j] = merge_defns(stat);
|
statements[j] = merge_defns(stat);
|
||||||
changed = true;
|
changed = true;
|
||||||
@@ -4297,6 +4320,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
stat.init = null;
|
stat.init = null;
|
||||||
changed = true;
|
changed = true;
|
||||||
} else if (stat.init instanceof AST_Var) {
|
} else if (stat.init instanceof AST_Var) {
|
||||||
|
prev_defs = defs;
|
||||||
defs = stat.init;
|
defs = stat.init;
|
||||||
exprs = merge_assigns(prev, stat.init);
|
exprs = merge_assigns(prev, stat.init);
|
||||||
if (exprs) {
|
if (exprs) {
|
||||||
@@ -9365,7 +9389,7 @@ Compressor.prototype.compress = function(node) {
|
|||||||
}
|
}
|
||||||
}, true)) {
|
}, true)) {
|
||||||
self.init = to_var(self.init, self.resolve());
|
self.init = to_var(self.init, self.resolve());
|
||||||
} else if (can_letify(self.init, compressor, 1)) {
|
} else if (self.init.can_letify(compressor, true)) {
|
||||||
self.init = to_let(self.init);
|
self.init = to_let(self.init);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10213,19 +10237,34 @@ Compressor.prototype.compress = function(node) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function can_letify(stat, compressor, assigned) {
|
(function(def) {
|
||||||
if (!(stat instanceof AST_Const)) return false;
|
def(AST_Node, return_false);
|
||||||
if (!compressor.option("module") && all(stat.definitions, function(defn) {
|
def(AST_Const, function(compressor, assigned) {
|
||||||
return defn.name instanceof AST_SymbolConst;
|
assigned = assigned ? 1 : 0;
|
||||||
})) return false;
|
var defns = this.definitions;
|
||||||
return all(stat.definitions, function(defn) {
|
if (!compressor.option("module") && all(defns, function(defn) {
|
||||||
return !defn.name.match_symbol(function(node) {
|
return defn.name instanceof AST_SymbolConst;
|
||||||
if (node instanceof AST_SymbolDeclaration) return node.definition().assignments != assigned;
|
})) return false;
|
||||||
}, true);
|
return all(defns, function(defn) {
|
||||||
|
return !defn.name.match_symbol(function(node) {
|
||||||
|
if (node instanceof AST_SymbolDeclaration) return node.definition().assignments != assigned;
|
||||||
|
}, true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
def(AST_Var, function(compressor) {
|
||||||
|
return all(this.definitions, function(defn) {
|
||||||
|
return !defn.name.match_symbol(function(node) {
|
||||||
|
if (!(node instanceof AST_SymbolDeclaration)) return false;
|
||||||
|
if (node.definition().first_decl !== node) return true;
|
||||||
|
return !safe_from_tdz(compressor, node);
|
||||||
|
}, true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})(function(node, func) {
|
||||||
|
node.DEFMETHOD("can_letify", func);
|
||||||
|
});
|
||||||
|
|
||||||
function can_varify(compressor, sym) {
|
function safe_from_tdz(compressor, sym) {
|
||||||
var def = sym.definition();
|
var def = sym.definition();
|
||||||
return (def.fixed || def.fixed === 0)
|
return (def.fixed || def.fixed === 0)
|
||||||
&& is_safe_lexical(def)
|
&& is_safe_lexical(def)
|
||||||
@@ -10233,25 +10272,25 @@ Compressor.prototype.compress = function(node) {
|
|||||||
&& !may_overlap(compressor, def);
|
&& !may_overlap(compressor, def);
|
||||||
}
|
}
|
||||||
|
|
||||||
function varify(self, compressor) {
|
AST_Definitions.DEFMETHOD("can_varify", function(compressor) {
|
||||||
if (all(self.definitions, function(defn) {
|
return all(this.definitions, function(defn) {
|
||||||
return !defn.name.match_symbol(function(node) {
|
return !defn.name.match_symbol(function(node) {
|
||||||
if (node instanceof AST_SymbolDeclaration) return !can_varify(compressor, node);
|
if (node instanceof AST_SymbolDeclaration) return !safe_from_tdz(compressor, node);
|
||||||
}, true);
|
}, true);
|
||||||
})) return to_var(self, compressor.find_parent(AST_Scope));
|
});
|
||||||
}
|
});
|
||||||
|
|
||||||
OPT(AST_Const, function(self, compressor) {
|
OPT(AST_Const, function(self, compressor) {
|
||||||
if (!compressor.option("varify")) return self;
|
if (!compressor.option("varify")) return self;
|
||||||
var decl = varify(self, compressor);
|
if (self.can_varify(compressor)) return to_var(self, compressor.find_parent(AST_Scope));
|
||||||
if (decl) return decl;
|
if (self.can_letify(compressor)) return to_let(self);
|
||||||
if (can_letify(self, compressor, 0)) return to_let(self);
|
|
||||||
return self;
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
OPT(AST_Let, function(self, compressor) {
|
OPT(AST_Let, function(self, compressor) {
|
||||||
if (!compressor.option("varify")) return self;
|
if (!compressor.option("varify")) return self;
|
||||||
return varify(self, compressor) || self;
|
if (self.can_varify(compressor)) return to_var(self, compressor.find_parent(AST_Scope));
|
||||||
|
return self;
|
||||||
});
|
});
|
||||||
|
|
||||||
function trim_optional_chain(node, compressor) {
|
function trim_optional_chain(node, compressor) {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
require("../tools/tty");
|
||||||
var createHash = require("crypto").createHash;
|
var createHash = require("crypto").createHash;
|
||||||
var fetch = require("./fetch");
|
var fetch = require("./fetch");
|
||||||
var spawn = require("child_process").spawn;
|
var spawn = require("child_process").spawn;
|
||||||
|
|||||||
@@ -1130,6 +1130,130 @@ default_init: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
join_let_var_1: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = "foo";
|
||||||
|
let b = "bar";
|
||||||
|
for (var c of [ a, b ])
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
let a = "foo", b = "bar";
|
||||||
|
for (var c of [ a, b ])
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_let_var_2: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
let a = "foo";
|
||||||
|
var b = "bar";
|
||||||
|
for (let c of [ a, b ])
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
let a = "foo", b = "bar";
|
||||||
|
for (let c of [ a, b ])
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_let_var_1: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = "foo";
|
||||||
|
let b = "bar";
|
||||||
|
for (var c of [ a, b ])
|
||||||
|
console.log(c);
|
||||||
|
function f() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f(f));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = "foo", c;
|
||||||
|
let b = "bar";
|
||||||
|
for (c of [ a, b ])
|
||||||
|
console.log(c);
|
||||||
|
function f() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f(f));
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_let_var_2: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
let a = "foo";
|
||||||
|
var b = "bar";
|
||||||
|
for (let c of [ a, b ])
|
||||||
|
console.log(c);
|
||||||
|
function f() {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
console.log(f(f));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
let a = "foo";
|
||||||
|
var b = "bar";
|
||||||
|
for (let c of [ a, b ])
|
||||||
|
console.log(c);
|
||||||
|
function f() {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
console.log(f(f));
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4191: {
|
issue_4191: {
|
||||||
options = {
|
options = {
|
||||||
functions: true,
|
functions: true,
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ rm -rf tmp/buble \
|
|||||||
@@ -309 +309 @@ export default class BlockStatement extends Node {
|
@@ -309 +309 @@ export default class BlockStatement extends Node {
|
||||||
- let cont = false; // TODO implement proper continue...
|
- let cont = false; // TODO implement proper continue...
|
||||||
+ let cont = !declarations; // TODO implement proper continue...
|
+ let cont = !declarations; // TODO implement proper continue...
|
||||||
|
--- a/src/program/types/VariableDeclaration.js
|
||||||
|
+++ b/src/program/types/VariableDeclaration.js
|
||||||
|
@@ -38 +38 @@ export default class VariableDeclaration extends Node {
|
||||||
|
- code.remove(c, declarator.id.start);
|
||||||
|
+ code.remove(c, declarator.id.start, lastDeclaratorIsPattern);
|
||||||
EOF
|
EOF
|
||||||
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
minify_in_situ "src" \
|
minify_in_situ "src" \
|
||||||
|
|||||||
Reference in New Issue
Block a user