@@ -443,10 +443,6 @@ Compressor.prototype.compress = function(node) {
|
||||
return def.name == "arguments" && def.scope.uses_arguments;
|
||||
}
|
||||
|
||||
function is_funarg(def) {
|
||||
return def.orig[0] instanceof AST_SymbolFunarg || def.orig[1] instanceof AST_SymbolFunarg;
|
||||
}
|
||||
|
||||
function cross_scope(def, sym) {
|
||||
do {
|
||||
if (def === sym) return false;
|
||||
@@ -2053,7 +2049,7 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
return make_node(AST_Assign, candidate, {
|
||||
operator: "=",
|
||||
left: make_node(AST_SymbolRef, candidate.name, candidate.name),
|
||||
left: node,
|
||||
right: rvalue,
|
||||
});
|
||||
}
|
||||
@@ -6229,51 +6225,46 @@ Compressor.prototype.compress = function(node) {
|
||||
var changed = false;
|
||||
var merged = Object.create(null);
|
||||
while (first.length && last.length) {
|
||||
var head = first.pop();
|
||||
var def = head.definition;
|
||||
if (!(def.id in prev)) continue;
|
||||
if (!references[def.id]) continue;
|
||||
var head_refs = {
|
||||
start: references[def.id].start,
|
||||
};
|
||||
var tail = last.shift();
|
||||
if (!tail) continue;
|
||||
var def = tail.definition;
|
||||
var tail_refs = references[def.id];
|
||||
if (!tail_refs) continue;
|
||||
tail_refs = { end: tail_refs.end };
|
||||
while (def.id in merged) def = merged[def.id];
|
||||
head_refs.end = references[def.id].end;
|
||||
tail_refs.start = references[def.id].start;
|
||||
var skipped = [];
|
||||
do {
|
||||
var tail = last.pop();
|
||||
if (!tail) continue;
|
||||
var head = first.shift();
|
||||
if (tail.index > head.index) continue;
|
||||
var id = tail.definition.id;
|
||||
var tail_refs = references[id];
|
||||
if (!tail_refs) continue;
|
||||
var id = head.definition.id;
|
||||
if (!(id in prev)) continue;
|
||||
var head_refs = references[id];
|
||||
if (!head_refs) continue;
|
||||
if (head_refs.start.block !== tail_refs.start.block
|
||||
|| !mergeable(head_refs, tail_refs)
|
||||
|| (head_refs.start.loop || !same_scope(def)) && !mergeable(tail_refs, head_refs)
|
||||
|| compressor.option("webkit") && is_funarg(def) !== is_funarg(tail.definition)
|
||||
|| !all(tail_refs, function(sym) {
|
||||
return sym.scope.find_variable(def.name) === def;
|
||||
})) {
|
||||
skipped.unshift(tail);
|
||||
|| compressor.option("webkit") && is_funarg(def) !== is_funarg(head.definition)
|
||||
|| !safe_to_rename(head_refs, def)
|
||||
|| !safe_to_rename(references[def.id], head.definition)) {
|
||||
skipped.push(head);
|
||||
continue;
|
||||
}
|
||||
var orig = [], refs = [];
|
||||
tail_refs.forEach(function(sym) {
|
||||
head_refs.forEach(function(sym) {
|
||||
sym.thedef = def;
|
||||
sym.name = def.name;
|
||||
if (sym instanceof AST_SymbolRef) {
|
||||
refs.push(sym);
|
||||
def.references.push(sym);
|
||||
} else {
|
||||
orig.push(sym);
|
||||
def.orig.push(sym);
|
||||
}
|
||||
});
|
||||
def.orig = orig.concat(def.orig);
|
||||
def.references = refs.concat(def.references);
|
||||
def.fixed = tail.definition.fixed && def.fixed;
|
||||
if (!head.definition.fixed) def.fixed = false;
|
||||
merged[id] = def;
|
||||
changed = true;
|
||||
break;
|
||||
} while (last.length);
|
||||
if (skipped.length) last = last.concat(skipped);
|
||||
} while (first.length);
|
||||
if (skipped.length) first = skipped.concat(first);
|
||||
}
|
||||
return changed;
|
||||
|
||||
@@ -6357,6 +6348,12 @@ Compressor.prototype.compress = function(node) {
|
||||
function mergeable(head, tail) {
|
||||
return must_visit(head.start, head.end) || must_visit(head.start, tail.start);
|
||||
}
|
||||
|
||||
function safe_to_rename(refs, def) {
|
||||
return all(refs, function(sym) {
|
||||
return sym.scope.find_variable(def.name) === def;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function fill_holes(orig, elements) {
|
||||
@@ -8072,9 +8069,7 @@ Compressor.prototype.compress = function(node) {
|
||||
return exp.drop_side_effect_free(compressor, first_in_statement);
|
||||
}
|
||||
function convert_spread(node) {
|
||||
return node instanceof AST_Spread ? make_node(AST_Array, node, {
|
||||
elements: [ node ]
|
||||
}) : node;
|
||||
return node instanceof AST_Spread ? make_node(AST_Array, node, { elements: [ node ] }) : node;
|
||||
}
|
||||
def(AST_Node, return_this);
|
||||
def(AST_Accessor, return_null);
|
||||
@@ -8396,20 +8391,20 @@ Compressor.prototype.compress = function(node) {
|
||||
node = alternative ? make_node(AST_Binary, this, {
|
||||
operator: "||",
|
||||
left: this.condition,
|
||||
right: alternative
|
||||
right: alternative,
|
||||
}) : this.condition.drop_side_effect_free(compressor);
|
||||
} else if (!alternative) {
|
||||
node = make_node(AST_Binary, this, {
|
||||
operator: "&&",
|
||||
left: this.condition,
|
||||
right: consequent
|
||||
right: consequent,
|
||||
});
|
||||
} else {
|
||||
node = this.clone();
|
||||
node.consequent = consequent;
|
||||
node.alternative = alternative;
|
||||
}
|
||||
if (!compressor.option("ie")) return node;
|
||||
if (!exprs) return node;
|
||||
if (node) exprs.push(node);
|
||||
return exprs.length == 0 ? null : make_sequence(this, exprs);
|
||||
});
|
||||
@@ -8442,9 +8437,7 @@ Compressor.prototype.compress = function(node) {
|
||||
return !(node instanceof AST_Spread);
|
||||
})) return this;
|
||||
return make_sequence(this, values.map(function(node) {
|
||||
return node instanceof AST_Spread ? make_node(AST_Object, node, {
|
||||
properties: [ node ],
|
||||
}) : node;
|
||||
return node instanceof AST_Spread ? make_node(AST_Object, node, { properties: [ node ] }) : node;
|
||||
}));
|
||||
});
|
||||
def(AST_ObjectIdentity, return_null);
|
||||
|
||||
@@ -78,6 +78,7 @@ function minify(files, options) {
|
||||
enclose: false,
|
||||
ie: false,
|
||||
ie8: false,
|
||||
keep_fargs: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
nameCache: null,
|
||||
@@ -99,6 +100,7 @@ function minify(files, options) {
|
||||
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
|
||||
if (options.ie8) options.ie = options.ie || options.ie8;
|
||||
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output" ]);
|
||||
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle" ]);
|
||||
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||
if (options.v8) set_shorthand("v8", options, [ "mangle", "output" ]);
|
||||
@@ -109,6 +111,7 @@ function minify(files, options) {
|
||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||
eval: false,
|
||||
ie: false,
|
||||
keep_fargs: false,
|
||||
keep_fnames: false,
|
||||
properties: false,
|
||||
reserved: [],
|
||||
|
||||
34
lib/scope.js
34
lib/scope.js
@@ -92,15 +92,19 @@ SymbolDef.prototype = {
|
||||
if (def && def !== self) return def.redefined() || def;
|
||||
},
|
||||
unmangleable: function(options) {
|
||||
return this.global && !options.toplevel
|
||||
|| this.exported
|
||||
|| this.undeclared
|
||||
|| !options.eval && this.scope.pinned()
|
||||
|| options.keep_fnames
|
||||
&& (this.orig[0] instanceof AST_SymbolClass
|
||||
|| this.orig[0] instanceof AST_SymbolDefClass
|
||||
|| this.orig[0] instanceof AST_SymbolDefun
|
||||
|| this.orig[0] instanceof AST_SymbolLambda);
|
||||
if (this.exported) return true;
|
||||
if (this.undeclared) return true;
|
||||
if (!options.eval && this.scope.pinned()) return true;
|
||||
if (options.keep_fargs && is_funarg(this)) return true;
|
||||
if (options.keep_fnames) {
|
||||
var sym = this.orig[0];
|
||||
if (sym instanceof AST_SymbolClass) return true;
|
||||
if (sym instanceof AST_SymbolDefClass) return true;
|
||||
if (sym instanceof AST_SymbolDefun) return true;
|
||||
if (sym instanceof AST_SymbolLambda) return true;
|
||||
}
|
||||
if (!options.toplevel && this.global) return true;
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -113,6 +117,10 @@ DEF_BITPROPS(SymbolDef, [
|
||||
"undeclared",
|
||||
]);
|
||||
|
||||
function is_funarg(def) {
|
||||
return def.orig[0] instanceof AST_SymbolFunarg || def.orig[1] instanceof AST_SymbolFunarg;
|
||||
}
|
||||
|
||||
var unary_side_effects = makePredicate("delete ++ --");
|
||||
|
||||
function is_lhs(node, parent) {
|
||||
@@ -473,8 +481,11 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (!options) {
|
||||
s._var_names = undefined;
|
||||
} else if (options.keep_fnames) {
|
||||
s.functions.each(function(d) {
|
||||
} else {
|
||||
if (options.keep_fargs && s instanceof AST_Lambda) s.each_argname(function(arg) {
|
||||
push_uniq(def.scope.enclosed, arg.definition());
|
||||
});
|
||||
if (options.keep_fnames) s.functions.each(function(d) {
|
||||
push_uniq(def.scope.enclosed, d);
|
||||
});
|
||||
}
|
||||
@@ -579,6 +590,7 @@ function _default_mangler_options(options) {
|
||||
options = defaults(options, {
|
||||
eval : false,
|
||||
ie : false,
|
||||
keep_fargs : false,
|
||||
keep_fnames : false,
|
||||
reserved : [],
|
||||
toplevel : false,
|
||||
|
||||
Reference in New Issue
Block a user