[Pkg-javascript-commits] [uglifyjs] 253/491: enhance `properties` (#2412)
Jonas Smedegaard
dr at jones.dk
Wed Feb 14 19:51:41 UTC 2018
This is an automated email from the git hooks/post-receive script.
js pushed a commit to annotated tag debian/3.3.10-1
in repository uglifyjs.
commit 8428326ea120dece51b70d7bba63dda8eda14fd6
Author: Alex Lam S.L <alexlamsl at gmail.com>
Date: Sun Oct 29 04:11:26 2017 +0800
enhance `properties` (#2412)
- trim array items only if `side_effects`
- extend to non-identifier properties
---
lib/compress.js | 151 ++++++++++++++++++++++++-------------------
test/compress/evaluate.js | 2 +
test/compress/properties.js | 51 ++++++++++-----
test/compress/reduce_vars.js | 1 +
4 files changed, 124 insertions(+), 81 deletions(-)
diff --git a/lib/compress.js b/lib/compress.js
index 4817ec5..a1db985 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -4537,59 +4537,72 @@ merge(Compressor.prototype, {
});
OPT(AST_Sub, function(self, compressor){
+ var expr = self.expression;
+ var prop = self.property;
if (compressor.option("properties")) {
- var prop = self.property;
- if (prop instanceof AST_String) {
- prop = prop.getValue();
- if (is_identifier_string(prop)) {
+ var key = prop.evaluate(compressor);
+ if (key !== prop) {
+ var property = "" + key;
+ if (is_identifier_string(property)
+ && property.length <= prop.print_to_string().length + 1) {
return make_node(AST_Dot, self, {
- expression : self.expression,
- property : prop
+ expression: expr,
+ property: property
}).optimize(compressor);
}
- var v = parseFloat(prop);
- if (!isNaN(v) && v.toString() == prop) {
- self.property = make_node(AST_Number, self.property, {
- value: v
- });
+ if (!(prop instanceof AST_Number)) {
+ var value = parseFloat(property);
+ if (value.toString() == property) {
+ prop = self.property = make_node(AST_Number, prop, {
+ value: value
+ });
+ }
}
}
- if (prop instanceof AST_Number && self.expression instanceof AST_Array) {
- prop = prop.getValue();
- var elements = self.expression.elements;
- if (prop in elements) {
- var flatten = true;
- var values = [];
- for (var i = elements.length; --i > prop;) {
- var value = elements[i].drop_side_effect_free(compressor);
- if (value) {
- values.unshift(value);
- if (flatten && value.has_side_effects(compressor)) flatten = false;
- }
- }
- var retValue = elements[prop];
- retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
- if (!flatten) values.unshift(retValue);
- while (--i >= 0) {
- var value = elements[i].drop_side_effect_free(compressor);
- if (value) values.unshift(value);
- else prop--;
+ }
+ if (is_lhs(self, compressor.parent())) return self;
+ if (compressor.option("properties") && key !== prop) {
+ var node = self.flatten_object(property);
+ if (node) {
+ expr = self.expression = node.expression;
+ prop = self.property = node.property;
+ }
+ }
+ if (compressor.option("properties") && compressor.option("side_effects")
+ && prop instanceof AST_Number && expr instanceof AST_Array) {
+ var index = prop.getValue();
+ var elements = expr.elements;
+ if (index in elements) {
+ var flatten = true;
+ var values = [];
+ for (var i = elements.length; --i > index;) {
+ var value = elements[i].drop_side_effect_free(compressor);
+ if (value) {
+ values.unshift(value);
+ if (flatten && value.has_side_effects(compressor)) flatten = false;
}
- if (flatten) {
- values.push(retValue);
- return make_sequence(self, values).optimize(compressor);
- } else return make_node(AST_Sub, self, {
- expression: make_node(AST_Array, self.expression, {
- elements: values
- }),
- property: make_node(AST_Number, self.property, {
- value: prop
- })
- });
}
+ var retValue = elements[index];
+ retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
+ if (!flatten) values.unshift(retValue);
+ while (--i >= 0) {
+ var value = elements[i].drop_side_effect_free(compressor);
+ if (value) values.unshift(value);
+ else index--;
+ }
+ if (flatten) {
+ values.push(retValue);
+ return make_sequence(self, values).optimize(compressor);
+ } else return make_node(AST_Sub, self, {
+ expression: make_node(AST_Array, expr, {
+ elements: values
+ }),
+ property: make_node(AST_Number, prop, {
+ value: index
+ })
+ });
}
}
- if (is_lhs(self, compressor.parent())) return self;
var ev = self.evaluate(compressor);
if (ev !== self) {
ev = make_node_from_constant(ev, self).optimize(compressor);
@@ -4609,6 +4622,33 @@ merge(Compressor.prototype, {
return result;
});
+ AST_PropAccess.DEFMETHOD("flatten_object", function(key) {
+ var expr = this.expression;
+ if (expr instanceof AST_Object) {
+ var props = expr.properties;
+ for (var i = props.length; --i >= 0;) {
+ var prop = props[i];
+ if ("" + prop.key == key) {
+ if (!all(props, function(prop) {
+ return prop instanceof AST_ObjectKeyVal;
+ })) break;
+ var value = prop.value;
+ if (value instanceof AST_Function && value.contains_this()) break;
+ return make_node(AST_Sub, this, {
+ expression: make_node(AST_Array, expr, {
+ elements: props.map(function(prop) {
+ return prop.value;
+ })
+ }),
+ property: make_node(AST_Number, this, {
+ value: i
+ })
+ });
+ }
+ }
+ }
+ });
+
OPT(AST_Dot, function(self, compressor){
var def = self.resolve_defines(compressor);
if (def) {
@@ -4637,28 +4677,9 @@ merge(Compressor.prototype, {
}
}
if (is_lhs(self, compressor.parent())) return self;
- if (compressor.option("properties") && self.expression instanceof AST_Object) {
- var props = self.expression.properties;
- for (var i = props.length; --i >= 0;) {
- var prop = props[i];
- if (prop.key === self.property) {
- if (!all(props, function(prop) {
- return prop instanceof AST_ObjectKeyVal;
- })) break;
- var value = prop.value;
- if (value instanceof AST_Function && value.contains_this()) break;
- return make_node(AST_Sub, self, {
- expression: make_node(AST_Array, self.expression, {
- elements: props.map(function(prop) {
- return prop.value;
- })
- }),
- property: make_node(AST_Number, self, {
- value: i
- })
- }).optimize(compressor);
- }
- }
+ if (compressor.option("properties")) {
+ var node = self.flatten_object(self.property);
+ if (node) return node.optimize(compressor);
}
var ev = self.evaluate(compressor);
if (ev !== self) {
diff --git a/test/compress/evaluate.js b/test/compress/evaluate.js
index dc8ceb6..64728c0 100644
--- a/test/compress/evaluate.js
+++ b/test/compress/evaluate.js
@@ -390,6 +390,7 @@ prop_function: {
options = {
evaluate: true,
properties: true,
+ side_effects: true,
}
input: {
console.log(
@@ -634,6 +635,7 @@ prototype_function: {
options = {
evaluate: true,
properties: true,
+ side_effects: true,
}
input: {
var a = ({valueOf: 0}) < 1;
diff --git a/test/compress/properties.js b/test/compress/properties.js
index f435d37..1b5e7fc 100644
--- a/test/compress/properties.js
+++ b/test/compress/properties.js
@@ -1,7 +1,8 @@
keep_properties: {
options = {
- properties: false
- };
+ evaluate: true,
+ properties: false,
+ }
input: {
a["foo"] = "bar";
}
@@ -12,6 +13,7 @@ keep_properties: {
dot_properties: {
options = {
+ evaluate: true,
properties: true,
}
beautify = {
@@ -37,6 +39,7 @@ dot_properties: {
dot_properties_es5: {
options = {
+ evaluate: true,
properties: true,
}
beautify = {
@@ -61,8 +64,8 @@ dot_properties_es5: {
sub_properties: {
options = {
evaluate: true,
- properties: true
- };
+ properties: true,
+ }
input: {
a[0] = 0;
a["0"] = 1;
@@ -81,18 +84,18 @@ sub_properties: {
a[3.14] = 3;
a.if = 4;
a["foo bar"] = 5;
- a[NaN] = 6;
- a[null] = 7;
+ a.NaN = 6;
+ a.null = 7;
a[void 0] = 8;
}
}
evaluate_array_length: {
options = {
+ evaluate: true,
properties: true,
unsafe: true,
- evaluate: true
- };
+ }
input: {
a = [1, 2, 3].length;
a = [1, 2, 3].join()["len" + "gth"];
@@ -109,10 +112,10 @@ evaluate_array_length: {
evaluate_string_length: {
options = {
+ evaluate: true,
properties: true,
unsafe: true,
- evaluate: true
- };
+ }
input: {
a = "foo".length;
a = ("foo" + "bar")["len" + "gth"];
@@ -151,7 +154,8 @@ mangle_properties: {
mangle_unquoted_properties: {
options = {
- properties: false
+ evaluate: true,
+ properties: false,
}
mangle = {
properties: {
@@ -249,7 +253,8 @@ mangle_debug_suffix: {
mangle_debug_suffix_keep_quoted: {
options = {
- properties: false
+ evaluate: true,
+ properties: false,
}
mangle = {
properties: {
@@ -833,18 +838,29 @@ lhs_prop_2: {
unused: true,
}
input: {
+ [1][0] = 42;
(function(a) {
- a[2] = "g";
+ a.b = "g";
})("abc");
+ (function(a) {
+ a[2] = "g";
+ })("def");
+ (function(a) {
+ a[""] = "g";
+ })("ghi");
}
expect: {
- "abc"[2] = "g";
+ [1][0] = 42;
+ "abc".b = "g";
+ "def"[2] = "g";
+ "ghi"[""] = "g";
}
}
literal_duplicate_key_side_effects: {
options = {
properties: true,
+ side_effects: true,
}
input: {
console.log({
@@ -864,6 +880,7 @@ prop_side_effects_1: {
inline: true,
properties: true,
reduce_vars: true,
+ side_effects: true,
toplevel: true,
unused: true,
}
@@ -899,6 +916,7 @@ prop_side_effects_2: {
passes: 2,
properties: true,
reduce_vars: true,
+ side_effects: true,
toplevel: true,
unused: true,
}
@@ -906,11 +924,11 @@ prop_side_effects_2: {
var C = 1;
console.log(C);
var obj = {
- bar: function() {
+ "": function() {
return C + C;
}
};
- console.log(obj.bar());
+ console.log(obj[""]());
}
expect: {
console.log(1);
@@ -974,6 +992,7 @@ accessor_2: {
array_hole: {
options = {
properties: true,
+ side_effects: true,
}
input: {
console.log(
diff --git a/test/compress/reduce_vars.js b/test/compress/reduce_vars.js
index ac4fa40..d7fdee1 100644
--- a/test/compress/reduce_vars.js
+++ b/test/compress/reduce_vars.js
@@ -2973,6 +2973,7 @@ obj_var_2: {
passes: 2,
properties: true,
reduce_vars: true,
+ side_effects: true,
toplevel: true,
unsafe: true,
unused: true,
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git
More information about the Pkg-javascript-commits
mailing list