enhance default_values (#4450)
This commit is contained in:
157
lib/compress.js
157
lib/compress.js
@@ -3361,6 +3361,7 @@ merge(Compressor.prototype, {
|
||||
return this.consequent.is_defined(compressor) && this.alternative.is_defined(compressor);
|
||||
});
|
||||
def(AST_Constant, return_true);
|
||||
def(AST_Hole, return_false);
|
||||
def(AST_Lambda, return_true);
|
||||
def(AST_Object, return_true);
|
||||
def(AST_Sequence, function(compressor) {
|
||||
@@ -5566,71 +5567,7 @@ merge(Compressor.prototype, {
|
||||
node.definitions.forEach(function(def) {
|
||||
if (def.value) def.value = def.value.transform(tt);
|
||||
if (def.name instanceof AST_Destructured) {
|
||||
var value = def.value;
|
||||
var trimmer = new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_DefaultValue) return trim_default(tt, trimmer, node);
|
||||
if (node instanceof AST_DestructuredArray) {
|
||||
var save = value;
|
||||
if (value instanceof AST_SymbolRef) value = value.fixed_value();
|
||||
var values = value instanceof AST_Array && value.elements;
|
||||
var elements = [];
|
||||
node.elements.forEach(function(element, index) {
|
||||
if (element instanceof AST_Hole) return;
|
||||
value = values && values[index];
|
||||
element = element.transform(trimmer);
|
||||
if (element) elements[index] = element;
|
||||
});
|
||||
value = save;
|
||||
if (values && elements.length == 0) return null;
|
||||
for (var i = elements.length; --i >= 0;) {
|
||||
if (!elements[i]) elements[i] = make_node(AST_Hole, node.elements[i] || node);
|
||||
}
|
||||
node.elements = elements;
|
||||
return node;
|
||||
}
|
||||
if (node instanceof AST_DestructuredObject) {
|
||||
var save = value;
|
||||
if (value instanceof AST_SymbolRef) value = value.fixed_value();
|
||||
var values;
|
||||
if (value instanceof AST_Object) {
|
||||
values = Object.create(null);
|
||||
for (var i = 0; i < value.properties.length; i++) {
|
||||
var prop = value.properties[i];
|
||||
if (typeof prop.key != "string") {
|
||||
values = null;
|
||||
break;
|
||||
}
|
||||
values[prop.key] = prop.value;
|
||||
}
|
||||
}
|
||||
var properties = [];
|
||||
node.properties.forEach(function(prop) {
|
||||
var retain;
|
||||
if (prop.key instanceof AST_Node) {
|
||||
prop.key = prop.key.transform(tt);
|
||||
value = null;
|
||||
retain = prop.key.has_side_effects(compressor);
|
||||
} else {
|
||||
value = values && values[prop.key];
|
||||
retain = false;
|
||||
}
|
||||
if (retain && is_decl(prop.value)) {
|
||||
properties.push(prop);
|
||||
} else {
|
||||
var newValue = prop.value.transform(trimmer);
|
||||
if (newValue) {
|
||||
prop.value = newValue;
|
||||
properties.push(prop);
|
||||
}
|
||||
}
|
||||
});
|
||||
value = save;
|
||||
if (properties.length == 0 && value && !value.may_throw_on_access(compressor)) {
|
||||
return null;
|
||||
}
|
||||
node.properties = properties;
|
||||
return node;
|
||||
}
|
||||
var name = trim_destructured(def.name, def.value, function(node) {
|
||||
if (node instanceof AST_SymbolDeclaration) {
|
||||
if (!drop_vars) return node;
|
||||
if (node.definition().id in in_use_ids) return node;
|
||||
@@ -5639,11 +5576,10 @@ merge(Compressor.prototype, {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
var name = def.name.transform(trimmer);
|
||||
if (name) {
|
||||
flush();
|
||||
} else {
|
||||
value = value.drop_side_effect_free(compressor);
|
||||
var value = def.value.drop_side_effect_free(compressor);
|
||||
if (value) side_effects.push(value);
|
||||
}
|
||||
return;
|
||||
@@ -5807,6 +5743,17 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
return insert_statements(body, node, in_list);
|
||||
}
|
||||
if (node instanceof AST_Assign) {
|
||||
descend(node, tt);
|
||||
if (node.left instanceof AST_Destructured) {
|
||||
var lhs = trim_destructured(node.left, node.right, function(node) {
|
||||
if (node instanceof AST_SymbolRef) return node;
|
||||
});
|
||||
if (!lhs) return node.right;
|
||||
node.left = lhs;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
if (node instanceof AST_LabeledStatement && node.body instanceof AST_For) {
|
||||
// Certain combination of unused name + side effect leads to invalid AST:
|
||||
// https://github.com/mishoo/UglifyJS/issues/1830
|
||||
@@ -6094,6 +6041,82 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function trim_destructured(node, value, process) {
|
||||
var trimmer = new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_DefaultValue) {
|
||||
if (compressor.option("default_values") && value && value.is_defined(compressor)) {
|
||||
node = node.name;
|
||||
} else {
|
||||
return trim_default(tt, trimmer, node);
|
||||
}
|
||||
}
|
||||
if (node instanceof AST_DestructuredArray) {
|
||||
var save = value;
|
||||
if (value instanceof AST_SymbolRef) value = value.fixed_value();
|
||||
var values = value instanceof AST_Array && value.elements;
|
||||
var elements = [];
|
||||
node.elements.forEach(function(element, index) {
|
||||
if (element instanceof AST_Hole) return;
|
||||
value = values && values[index];
|
||||
element = element.transform(trimmer);
|
||||
if (element) elements[index] = element;
|
||||
});
|
||||
value = save;
|
||||
if (values && elements.length == 0) return null;
|
||||
for (var i = elements.length; --i >= 0;) {
|
||||
if (!elements[i]) elements[i] = make_node(AST_Hole, node.elements[i] || node);
|
||||
}
|
||||
node.elements = elements;
|
||||
return node;
|
||||
}
|
||||
if (node instanceof AST_DestructuredObject) {
|
||||
var save = value;
|
||||
if (value instanceof AST_SymbolRef) value = value.fixed_value();
|
||||
var values;
|
||||
if (value instanceof AST_Object) {
|
||||
values = Object.create(null);
|
||||
for (var i = 0; i < value.properties.length; i++) {
|
||||
var prop = value.properties[i];
|
||||
if (typeof prop.key != "string") {
|
||||
values = null;
|
||||
break;
|
||||
}
|
||||
values[prop.key] = prop.value;
|
||||
}
|
||||
}
|
||||
var properties = [];
|
||||
node.properties.forEach(function(prop) {
|
||||
var retain;
|
||||
if (prop.key instanceof AST_Node) {
|
||||
prop.key = prop.key.transform(tt);
|
||||
value = null;
|
||||
retain = prop.key.has_side_effects(compressor);
|
||||
} else {
|
||||
value = values && values[prop.key];
|
||||
retain = false;
|
||||
}
|
||||
if (retain && is_decl(prop.value)) {
|
||||
properties.push(prop);
|
||||
} else {
|
||||
var newValue = prop.value.transform(trimmer);
|
||||
if (newValue) {
|
||||
prop.value = newValue;
|
||||
properties.push(prop);
|
||||
}
|
||||
}
|
||||
});
|
||||
value = save;
|
||||
if (properties.length == 0 && value && !value.may_throw_on_access(compressor)) {
|
||||
return null;
|
||||
}
|
||||
node.properties = properties;
|
||||
return node;
|
||||
}
|
||||
return process(node);
|
||||
});
|
||||
return node.transform(trimmer);
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
|
||||
|
||||
@@ -543,6 +543,70 @@ unused_var_2: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
unused_value_assign_1: {
|
||||
options = {
|
||||
default_values: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
[] = [ console.log("PASS") ];
|
||||
}
|
||||
expect: {
|
||||
[ console.log("PASS") ];
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
unused_value_assign_2: {
|
||||
options = {
|
||||
default_values: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
[ a = console.log("FAIL") ] = [ "PASS" ];
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
[ a ] = [ "PASS" ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
unused_value_var_1: {
|
||||
options = {
|
||||
default_values: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var [] = [ console.log("PASS") ];
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
unused_value_var_2: {
|
||||
options = {
|
||||
default_values: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var [ a = console.log("FAIL") ] = [ "PASS" ];
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var [ a ] = [ "PASS" ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
mangle_var_1: {
|
||||
mangle = {
|
||||
toplevel: false,
|
||||
|
||||
Reference in New Issue
Block a user