parent
604caa09e7
commit
13062a4758
|
|
@ -75,6 +75,7 @@ function minify(files, options) {
|
||||||
options.mangle = defaults(options.mangle, {
|
options.mangle = defaults(options.mangle, {
|
||||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||||
eval: false,
|
eval: false,
|
||||||
|
group_voids: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
properties: false,
|
properties: false,
|
||||||
|
|
|
||||||
71
lib/scope.js
71
lib/scope.js
|
|
@ -400,6 +400,7 @@ AST_Symbol.DEFMETHOD("global", function(){
|
||||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
eval : false,
|
eval : false,
|
||||||
|
group_voids : false,
|
||||||
ie8 : false,
|
ie8 : false,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
reserved : [],
|
reserved : [],
|
||||||
|
|
@ -457,6 +458,18 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||||
|
|
||||||
|
if (options.group_voids) {
|
||||||
|
base54.reset();
|
||||||
|
base54.sort();
|
||||||
|
if (options.toplevel) this.group_voids(options);
|
||||||
|
else this.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_Scope && !(node instanceof AST_Toplevel)) {
|
||||||
|
node.group_voids(options);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
function collect(symbol) {
|
function collect(symbol) {
|
||||||
if (!member(symbol.name, options.reserved)) {
|
if (!member(symbol.name, options.reserved)) {
|
||||||
to_mangle.push(symbol);
|
to_mangle.push(symbol);
|
||||||
|
|
@ -464,11 +477,11 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
AST_Scope.DEFMETHOD("find_colliding_names", function(options, all) {
|
||||||
var cache = options.cache && options.cache.props;
|
var cache = options.cache && options.cache.props;
|
||||||
var avoid = Object.create(null);
|
var avoid = Object.create(null);
|
||||||
options.reserved.forEach(to_avoid);
|
options.reserved.forEach(to_avoid);
|
||||||
this.globals.each(add_def);
|
if (this.globals) this.globals.each(add_def);
|
||||||
this.walk(new TreeWalker(function(node) {
|
this.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Scope) node.variables.each(add_def);
|
if (node instanceof AST_Scope) node.variables.each(add_def);
|
||||||
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
||||||
|
|
@ -480,9 +493,9 @@ AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function add_def(def) {
|
function add_def(def) {
|
||||||
var name = def.name;
|
var name = def.mangled_name || def.name;
|
||||||
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
||||||
else if (!def.unmangleable(options)) return;
|
else if (!all && !def.unmangleable(options)) return;
|
||||||
to_avoid(name);
|
to_avoid(name);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -522,6 +535,56 @@ AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("group_voids", function(options) {
|
||||||
|
var avoid = this.find_colliding_names(options, true);
|
||||||
|
var cname = 0;
|
||||||
|
var name;
|
||||||
|
do {
|
||||||
|
name = base54(cname++);
|
||||||
|
} while (avoid[name] || !is_identifier(name));
|
||||||
|
var count = 0;
|
||||||
|
this.transform(new TreeTransformer(function(node) {
|
||||||
|
if (node instanceof AST_Undefined
|
||||||
|
|| node instanceof AST_UnaryPrefix
|
||||||
|
&& node.operator == "void"
|
||||||
|
&& node.expression.is_constant()) {
|
||||||
|
count++;
|
||||||
|
return new AST_SymbolRef({
|
||||||
|
name: name,
|
||||||
|
start: node.start,
|
||||||
|
end: node.end
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
if (count) {
|
||||||
|
for (var i = 0, len = this.body.length; i < len; i++) {
|
||||||
|
var stat = this.body[i];
|
||||||
|
if (stat instanceof AST_Var) {
|
||||||
|
stat.definitions.push(make_var_def(stat));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.body.push(new AST_Var({
|
||||||
|
definitions: [ make_var_def(this) ],
|
||||||
|
start: this.start,
|
||||||
|
end: this.end
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function make_var_def(node) {
|
||||||
|
return new AST_VarDef({
|
||||||
|
name: new AST_SymbolVar({
|
||||||
|
name: name,
|
||||||
|
start: node.start,
|
||||||
|
end: node.end
|
||||||
|
}),
|
||||||
|
value: null,
|
||||||
|
start: node.start,
|
||||||
|
end: node.end
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("tail_node", return_this);
|
AST_Node.DEFMETHOD("tail_node", return_this);
|
||||||
AST_Sequence.DEFMETHOD("tail_node", function() {
|
AST_Sequence.DEFMETHOD("tail_node", function() {
|
||||||
return this.expressions[this.expressions.length - 1];
|
return this.expressions[this.expressions.length - 1];
|
||||||
|
|
|
||||||
198
test/compress/group_voids.js
Normal file
198
test/compress/group_voids.js
Normal file
|
|
@ -0,0 +1,198 @@
|
||||||
|
group_voids: {
|
||||||
|
options = {
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
group_voids: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
x = void 0;
|
||||||
|
if (void 0 === b)
|
||||||
|
c = void 0;
|
||||||
|
function f1() {
|
||||||
|
var a = 1;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
function f2(undefined) {
|
||||||
|
var a = 2;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
var undefined = 3;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
console.log(void 0);
|
||||||
|
for (var a = 4;;);
|
||||||
|
var b = 4;
|
||||||
|
function f5() {
|
||||||
|
var c = 5;
|
||||||
|
var d = 5;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f6() {
|
||||||
|
try {
|
||||||
|
var a = 6;
|
||||||
|
console.log(void 0);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
x = void 0;
|
||||||
|
if (void 0 === b)
|
||||||
|
c = void 0;
|
||||||
|
function f1() {
|
||||||
|
var o = 1, a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function f2(o) {
|
||||||
|
var n = 2, a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
var o = 3, a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
console.log(a);
|
||||||
|
for(var o = 4;;);
|
||||||
|
var n = 4, a;
|
||||||
|
function v() {
|
||||||
|
var o = 5;
|
||||||
|
var n = 5;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f6() {
|
||||||
|
try {
|
||||||
|
var o = 6;
|
||||||
|
console.log(a);
|
||||||
|
} catch (o) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group_voids_toplevel: {
|
||||||
|
options = {
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
group_voids: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
x = void 0;
|
||||||
|
if (void 0 === b)
|
||||||
|
c = void 0;
|
||||||
|
function f1() {
|
||||||
|
var a = 1;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
function f2(undefined) {
|
||||||
|
var a = 2;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
var undefined = 3;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
console.log(void 0);
|
||||||
|
for (var a = 4;;);
|
||||||
|
var b = 4;
|
||||||
|
function f5() {
|
||||||
|
var c = 5;
|
||||||
|
var d = 5;
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f6() {
|
||||||
|
try {
|
||||||
|
var a = 6;
|
||||||
|
console.log(void 0);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = 0, a;
|
||||||
|
x = a;
|
||||||
|
if (a === b)
|
||||||
|
c = a;
|
||||||
|
function n() {
|
||||||
|
var o = 1;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function v(o) {
|
||||||
|
var n = 2;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function i() {
|
||||||
|
var o = 3;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
function l() {
|
||||||
|
console.log(a);
|
||||||
|
for(var o = 4;;);
|
||||||
|
var n = 4;
|
||||||
|
function v() {
|
||||||
|
var o = 5;
|
||||||
|
var n = 5;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function r() {
|
||||||
|
try {
|
||||||
|
var o = 6;
|
||||||
|
console.log(a);
|
||||||
|
} catch (o) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
group_voids_catch: {
|
||||||
|
options = {
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
group_voids: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
f();
|
||||||
|
function f() {
|
||||||
|
var a = 1;
|
||||||
|
console.log(void 0);
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (undefined) {
|
||||||
|
console.log(void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
f();
|
||||||
|
function f() {
|
||||||
|
var o = 1, a;
|
||||||
|
console.log(a);
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (o) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user