support computed property name in object literal (#4268)

This commit is contained in:
Alex Lam S.L
2020-11-08 15:38:32 +00:00
committed by GitHub
parent 810cd40356
commit 91fc1c82b5
10 changed files with 166 additions and 139 deletions

View File

@@ -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() {