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);
|
return this.consequent.is_defined(compressor) && this.alternative.is_defined(compressor);
|
||||||
});
|
});
|
||||||
def(AST_Constant, return_true);
|
def(AST_Constant, return_true);
|
||||||
|
def(AST_Hole, return_false);
|
||||||
def(AST_Lambda, return_true);
|
def(AST_Lambda, return_true);
|
||||||
def(AST_Object, return_true);
|
def(AST_Object, return_true);
|
||||||
def(AST_Sequence, function(compressor) {
|
def(AST_Sequence, function(compressor) {
|
||||||
@@ -5566,71 +5567,7 @@ merge(Compressor.prototype, {
|
|||||||
node.definitions.forEach(function(def) {
|
node.definitions.forEach(function(def) {
|
||||||
if (def.value) def.value = def.value.transform(tt);
|
if (def.value) def.value = def.value.transform(tt);
|
||||||
if (def.name instanceof AST_Destructured) {
|
if (def.name instanceof AST_Destructured) {
|
||||||
var value = def.value;
|
var name = trim_destructured(def.name, def.value, function(node) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_SymbolDeclaration) {
|
if (node instanceof AST_SymbolDeclaration) {
|
||||||
if (!drop_vars) return node;
|
if (!drop_vars) return node;
|
||||||
if (node.definition().id in in_use_ids) return node;
|
if (node.definition().id in in_use_ids) return node;
|
||||||
@@ -5639,11 +5576,10 @@ merge(Compressor.prototype, {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var name = def.name.transform(trimmer);
|
|
||||||
if (name) {
|
if (name) {
|
||||||
flush();
|
flush();
|
||||||
} else {
|
} else {
|
||||||
value = value.drop_side_effect_free(compressor);
|
var value = def.value.drop_side_effect_free(compressor);
|
||||||
if (value) side_effects.push(value);
|
if (value) side_effects.push(value);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -5807,6 +5743,17 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return insert_statements(body, node, in_list);
|
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) {
|
if (node instanceof AST_LabeledStatement && node.body instanceof AST_For) {
|
||||||
// Certain combination of unused name + side effect leads to invalid AST:
|
// Certain combination of unused name + side effect leads to invalid AST:
|
||||||
// https://github.com/mishoo/UglifyJS/issues/1830
|
// https://github.com/mishoo/UglifyJS/issues/1830
|
||||||
@@ -6094,6 +6041,82 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
return node;
|
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) {
|
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
|
||||||
|
|||||||
@@ -543,6 +543,70 @@ unused_var_2: {
|
|||||||
node_version: ">=6"
|
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_var_1: {
|
||||||
mangle = {
|
mangle = {
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
|
|||||||
Reference in New Issue
Block a user