@@ -2004,7 +2004,7 @@ merge(Compressor.prototype, {
|
||||
if (this.properties[i].value instanceof AST_Accessor) return true;
|
||||
return false;
|
||||
});
|
||||
def(AST_Function, return_false);
|
||||
def(AST_Lambda, return_false);
|
||||
def(AST_UnaryPostfix, return_false);
|
||||
def(AST_UnaryPrefix, function() {
|
||||
return this.operator == "void";
|
||||
@@ -2023,8 +2023,9 @@ merge(Compressor.prototype, {
|
||||
})
|
||||
def(AST_Dot, function(compressor) {
|
||||
if (!is_strict(compressor)) return false;
|
||||
if (this.expression instanceof AST_Function && this.property == "prototype") return false;
|
||||
return true;
|
||||
var exp = this.expression;
|
||||
if (exp instanceof AST_SymbolRef) exp = exp.fixed_value();
|
||||
return !(exp instanceof AST_Lambda && this.property == "prototype");
|
||||
});
|
||||
def(AST_Sequence, function(compressor) {
|
||||
return this.tail_node()._dot_throw(compressor);
|
||||
@@ -3009,11 +3010,18 @@ merge(Compressor.prototype, {
|
||||
if (self.uses_eval || self.uses_with) return;
|
||||
var drop_funcs = !(self instanceof AST_Toplevel) || compressor.toplevel.funcs;
|
||||
var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars;
|
||||
var assign_as_unused = /keep_assign/.test(compressor.option("unused")) ? return_false : function(node) {
|
||||
var assign_as_unused = /keep_assign/.test(compressor.option("unused")) ? return_false : function(node, props) {
|
||||
var sym;
|
||||
if (node instanceof AST_Assign && (node.write_only || node.operator == "=")) {
|
||||
return node.left;
|
||||
sym = node.left;
|
||||
} else if (node instanceof AST_Unary && node.write_only) {
|
||||
sym = node.expression;
|
||||
}
|
||||
if (node instanceof AST_Unary && node.write_only) return node.expression;
|
||||
while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
|
||||
if (sym instanceof AST_Sub) props.unshift(sym.property);
|
||||
sym = sym.expression;
|
||||
}
|
||||
return sym;
|
||||
};
|
||||
var in_use = [];
|
||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
||||
@@ -3089,17 +3097,26 @@ merge(Compressor.prototype, {
|
||||
function before(node, descend, in_list) {
|
||||
var parent = tt.parent();
|
||||
if (drop_vars) {
|
||||
var sym = assign_as_unused(node);
|
||||
var props = [], sym = assign_as_unused(node, props);
|
||||
if (sym instanceof AST_SymbolRef) {
|
||||
var def = sym.definition();
|
||||
var in_use = def.id in in_use_ids;
|
||||
var value = null;
|
||||
if (node instanceof AST_Assign) {
|
||||
if (!in_use || def.id in fixed_ids && fixed_ids[def.id] !== node) {
|
||||
return maintain_this_binding(parent, node, node.right.transform(tt));
|
||||
if (!in_use || node.left === sym && def.id in fixed_ids && fixed_ids[def.id] !== node) {
|
||||
value = node.right;
|
||||
}
|
||||
} else if (!in_use) return make_node(AST_Number, node, {
|
||||
value: 0
|
||||
});
|
||||
} else if (!in_use) {
|
||||
value = make_node(AST_Number, node, {
|
||||
value: 0
|
||||
});
|
||||
}
|
||||
if (value) {
|
||||
props.push(value);
|
||||
return maintain_this_binding(parent, node, make_sequence(node, props.map(function(prop) {
|
||||
return prop.transform(tt);
|
||||
})));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (scope !== self) return;
|
||||
@@ -3277,12 +3294,15 @@ merge(Compressor.prototype, {
|
||||
self.transform(tt);
|
||||
|
||||
function scan_ref_scoped(node, descend) {
|
||||
var node_def, sym = assign_as_unused(node);
|
||||
var node_def, props = [], sym = assign_as_unused(node, props);
|
||||
if (sym instanceof AST_SymbolRef
|
||||
&& self.variables.get(sym.name) === (node_def = sym.definition())) {
|
||||
props.forEach(function(prop) {
|
||||
prop.walk(tw);
|
||||
});
|
||||
if (node instanceof AST_Assign) {
|
||||
node.right.walk(tw);
|
||||
if (!node_def.chained && node.left.fixed_value() === node.right) {
|
||||
if (node.left === sym && !node_def.chained && sym.fixed_value() === node.right) {
|
||||
fixed_ids[node_def.id] = node;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4619,3 +4619,26 @@ issue_2914_2: {
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_805: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function Foo(){}
|
||||
Foo.prototype = {};
|
||||
Foo.prototype.bar = 42;
|
||||
return Foo;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function Foo(){}
|
||||
(Foo.prototype = {}).bar = 42;
|
||||
return Foo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1719,3 +1719,69 @@ issue_2846: {
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_805_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
var unused = function() {};
|
||||
unused.prototype[a()] = 42;
|
||||
(unused.prototype.bar = function() {
|
||||
console.log("bar");
|
||||
})();
|
||||
return unused;
|
||||
})(function() {
|
||||
console.log("foo");
|
||||
return "foo";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
console.log("foo"),
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_805_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
function unused() {}
|
||||
unused.prototype[a()] = 42;
|
||||
(unused.prototype.bar = function() {
|
||||
console.log("bar");
|
||||
})();
|
||||
return unused;
|
||||
})(function() {
|
||||
console.log("foo");
|
||||
return "foo";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
console.log("foo"),
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ describe("test/jetstream.js", function() {
|
||||
this.timeout(20 * 60 * 1000);
|
||||
[
|
||||
"-mc",
|
||||
"-mc keep_fargs=false,passes=3,pure_getters,unsafe,unsafe_comps,unsafe_math,unsafe_proto",
|
||||
"-mc keep_fargs=false,passes=3,unsafe,unsafe_comps,unsafe_math,unsafe_proto",
|
||||
].forEach(function(options) {
|
||||
it("Should pass with options " + options, function(done) {
|
||||
var args = options.split(/ /);
|
||||
|
||||
Reference in New Issue
Block a user