support computed property name in object literal (#4268)
This commit is contained in:
106
lib/compress.js
106
lib/compress.js
@@ -1749,11 +1749,10 @@ merge(Compressor.prototype, {
|
||||
}
|
||||
} else if (expr instanceof AST_Object) {
|
||||
expr.properties.forEach(function(prop) {
|
||||
if (prop instanceof AST_ObjectKeyVal) {
|
||||
hit_stack.push(prop);
|
||||
extract_candidates(prop.value);
|
||||
hit_stack.pop();
|
||||
}
|
||||
hit_stack.push(prop);
|
||||
if (prop.key instanceof AST_Node) extract_candidates(prop.key);
|
||||
if (prop instanceof AST_ObjectKeyVal) extract_candidates(prop.value);
|
||||
hit_stack.pop();
|
||||
});
|
||||
} else if (expr instanceof AST_Sequence) {
|
||||
expr.expressions.forEach(extract_candidates);
|
||||
@@ -1799,7 +1798,7 @@ merge(Compressor.prototype, {
|
||||
if (parent instanceof AST_Exit) return node;
|
||||
if (parent instanceof AST_If) return node;
|
||||
if (parent instanceof AST_IterationStatement) return node;
|
||||
if (parent instanceof AST_ObjectKeyVal) return node;
|
||||
if (parent instanceof AST_ObjectProperty) return node;
|
||||
if (parent instanceof AST_PropAccess) return node;
|
||||
if (parent instanceof AST_Sequence) {
|
||||
return (parent.tail_node() === node ? find_stop : find_stop_unused)(parent, level + 1);
|
||||
@@ -1857,7 +1856,7 @@ merge(Compressor.prototype, {
|
||||
if (parent.condition !== node) return node;
|
||||
return find_stop_value(parent, level + 1);
|
||||
}
|
||||
if (parent instanceof AST_ObjectKeyVal) {
|
||||
if (parent instanceof AST_ObjectProperty) {
|
||||
var obj = scanner.parent(level + 1);
|
||||
return all(obj.properties, function(prop) {
|
||||
return prop instanceof AST_ObjectKeyVal;
|
||||
@@ -1905,7 +1904,7 @@ merge(Compressor.prototype, {
|
||||
if (parent instanceof AST_Exit) return find_stop_unused(parent, level + 1);
|
||||
if (parent instanceof AST_If) return find_stop_unused(parent, level + 1);
|
||||
if (parent instanceof AST_IterationStatement) return node;
|
||||
if (parent instanceof AST_ObjectKeyVal) {
|
||||
if (parent instanceof AST_ObjectProperty) {
|
||||
var obj = scanner.parent(level + 1);
|
||||
return all(obj.properties, function(prop) {
|
||||
return prop instanceof AST_ObjectKeyVal;
|
||||
@@ -2699,9 +2698,12 @@ merge(Compressor.prototype, {
|
||||
if (prop instanceof AST_Node) break;
|
||||
prop = "" + prop;
|
||||
var diff = prop == "__proto__" || compressor.has_directive("use strict") ? function(node) {
|
||||
return node.key != prop && node.key.name != prop;
|
||||
return typeof node.key == "string" && node.key != prop;
|
||||
} : function(node) {
|
||||
return node.key.name != prop;
|
||||
if (node instanceof AST_ObjectGetter || node instanceof AST_ObjectSetter) {
|
||||
return typeof node.key == "string" && node.key != prop;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (!all(value.properties, diff)) break;
|
||||
value.properties.push(make_node(AST_ObjectKeyVal, node, {
|
||||
@@ -2986,10 +2988,9 @@ merge(Compressor.prototype, {
|
||||
def(AST_Lambda, return_false);
|
||||
def(AST_Null, return_true);
|
||||
def(AST_Object, function(compressor) {
|
||||
if (!is_strict(compressor)) return false;
|
||||
for (var i = this.properties.length; --i >=0;)
|
||||
if (this.properties[i].value instanceof AST_Accessor) return true;
|
||||
return false;
|
||||
return is_strict(compressor) && !all(this.properties, function(prop) {
|
||||
return prop instanceof AST_ObjectKeyVal;
|
||||
});
|
||||
});
|
||||
def(AST_Sequence, function(compressor) {
|
||||
return this.tail_node()._dot_throw(compressor);
|
||||
@@ -3585,8 +3586,12 @@ merge(Compressor.prototype, {
|
||||
var val = {};
|
||||
for (var i = 0; i < this.properties.length; i++) {
|
||||
var prop = this.properties[i];
|
||||
if (!(prop instanceof AST_ObjectKeyVal)) return this;
|
||||
var key = prop.key;
|
||||
if (key instanceof AST_Symbol) key = key.name;
|
||||
if (key instanceof AST_Node) {
|
||||
key = key._eval(compressor, ignore_side_effects, cached, depth);
|
||||
if (key === prop.key) return this;
|
||||
}
|
||||
if (prop.value instanceof AST_Function) {
|
||||
if (typeof Object.prototype[key] == "function") return this;
|
||||
continue;
|
||||
@@ -4108,7 +4113,8 @@ merge(Compressor.prototype, {
|
||||
return any(this.properties, compressor);
|
||||
});
|
||||
def(AST_ObjectProperty, function(compressor) {
|
||||
return this.value.has_side_effects(compressor);
|
||||
return this.key instanceof AST_Node && this.key.has_side_effects(compressor)
|
||||
|| this.value.has_side_effects(compressor);
|
||||
});
|
||||
def(AST_Sub, function(compressor) {
|
||||
return this.expression.may_throw_on_access(compressor)
|
||||
@@ -4220,7 +4226,8 @@ merge(Compressor.prototype, {
|
||||
return any(this.properties, compressor);
|
||||
});
|
||||
def(AST_ObjectProperty, function(compressor) {
|
||||
return this.value.may_throw(compressor);
|
||||
return this.key instanceof AST_Node && this.key.may_throw(compressor)
|
||||
|| this.value.may_throw(compressor);
|
||||
});
|
||||
def(AST_Return, function(compressor) {
|
||||
return this.value && this.value.may_throw(compressor);
|
||||
@@ -4316,7 +4323,7 @@ merge(Compressor.prototype, {
|
||||
return all(this.properties);
|
||||
});
|
||||
def(AST_ObjectProperty, function() {
|
||||
return this.value.is_constant_expression();
|
||||
return typeof this.key == "string" && this.value.is_constant_expression();
|
||||
});
|
||||
def(AST_Unary, function() {
|
||||
return this.expression.is_constant_expression();
|
||||
@@ -5742,7 +5749,7 @@ merge(Compressor.prototype, {
|
||||
return right instanceof AST_Object
|
||||
&& right.properties.length > 0
|
||||
&& all(right.properties, function(prop) {
|
||||
return prop instanceof AST_ObjectKeyVal;
|
||||
return prop instanceof AST_ObjectKeyVal && typeof prop.key == "string";
|
||||
})
|
||||
&& all(def.references, function(ref) {
|
||||
return ref.fixed_value() === right;
|
||||
@@ -5932,12 +5939,14 @@ merge(Compressor.prototype, {
|
||||
return safe_to_drop(this, compressor) ? null : this;
|
||||
});
|
||||
def(AST_Object, function(compressor, first_in_statement) {
|
||||
var values = trim(this.properties, compressor, first_in_statement);
|
||||
var exprs = [];
|
||||
this.properties.forEach(function(prop) {
|
||||
if (prop.key instanceof AST_Node) exprs.push(prop.key);
|
||||
exprs.push(prop.value);
|
||||
});
|
||||
var values = trim(exprs, compressor, first_in_statement);
|
||||
return values && make_sequence(this, values);
|
||||
});
|
||||
def(AST_ObjectProperty, function(compressor, first_in_statement) {
|
||||
return this.value.drop_side_effect_free(compressor, first_in_statement);
|
||||
});
|
||||
def(AST_Sequence, function(compressor, first_in_statement) {
|
||||
var expressions = trim(this.expressions, compressor, first_in_statement);
|
||||
if (!expressions) return null;
|
||||
@@ -9317,22 +9326,21 @@ merge(Compressor.prototype, {
|
||||
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;
|
||||
if (!safe_to_flatten(prop.value, compressor)) 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
|
||||
if (prop.key != key) continue;
|
||||
if (!all(props, function(prop) {
|
||||
return prop instanceof AST_ObjectKeyVal && typeof prop.key == "string";
|
||||
})) break;
|
||||
if (!safe_to_flatten(prop.value, compressor)) 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
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -9402,22 +9410,22 @@ merge(Compressor.prototype, {
|
||||
var keys = new Dictionary();
|
||||
var values = [];
|
||||
self.properties.forEach(function(prop) {
|
||||
if (typeof prop.key != "string") {
|
||||
if (prop.key instanceof AST_Node) {
|
||||
var key = prop.key.evaluate(compressor);
|
||||
if (key !== prop.key) prop.key = "" + key;
|
||||
}
|
||||
if (prop instanceof AST_ObjectKeyVal && typeof prop.key == "string") {
|
||||
if (prop.value.has_side_effects(compressor)) flush();
|
||||
keys.add(prop.key, prop.value);
|
||||
} else {
|
||||
flush();
|
||||
values.push(prop);
|
||||
return;
|
||||
}
|
||||
if (prop.value.has_side_effects(compressor)) {
|
||||
flush();
|
||||
}
|
||||
keys.add(prop.key, prop.value);
|
||||
});
|
||||
flush();
|
||||
if (self.properties.length != values.length) {
|
||||
return make_node(AST_Object, self, {
|
||||
properties: values
|
||||
});
|
||||
}
|
||||
if (self.properties.length != values.length) return make_node(AST_Object, self, {
|
||||
properties: values
|
||||
});
|
||||
return self;
|
||||
|
||||
function flush() {
|
||||
|
||||
Reference in New Issue
Block a user