support class static initialization block (#5488)
This commit is contained in:
@@ -1146,7 +1146,7 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
}
|
||||
props.forEach(function(prop) {
|
||||
if (!prop.static || prop instanceof AST_ClassField && prop.value.contains_this()) {
|
||||
if (!prop.static || is_static_field_or_init(prop) && prop.value.contains_this()) {
|
||||
push(tw);
|
||||
prop.value.walk(tw);
|
||||
pop(tw);
|
||||
@@ -1156,6 +1156,14 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
return true;
|
||||
});
|
||||
def(AST_ClassInitBlock, function(tw, descend, compressor) {
|
||||
var node = this;
|
||||
push(tw);
|
||||
reset_variables(tw, compressor, node);
|
||||
descend();
|
||||
pop_scope(tw, node);
|
||||
return true;
|
||||
});
|
||||
def(AST_Conditional, function(tw) {
|
||||
this.condition.walk(tw);
|
||||
push(tw);
|
||||
@@ -1843,6 +1851,10 @@ Compressor.prototype.compress = function(node) {
|
||||
|| compressor.option("unsafe") && global_names[this.name];
|
||||
});
|
||||
|
||||
function is_static_field_or_init(prop) {
|
||||
return prop.static && prop.value && (prop instanceof AST_ClassField || prop instanceof AST_ClassInit);
|
||||
}
|
||||
|
||||
function declarations_only(node) {
|
||||
return all(node.definitions, function(var_def) {
|
||||
return !var_def.value;
|
||||
@@ -1852,8 +1864,7 @@ Compressor.prototype.compress = function(node) {
|
||||
function is_declaration(stat, lexical) {
|
||||
if (stat instanceof AST_DefClass) return lexical && !stat.extends && all(stat.properties, function(prop) {
|
||||
if (prop.key instanceof AST_Node) return false;
|
||||
if (prop instanceof AST_ClassField && prop.static && prop.value) return false;
|
||||
return true;
|
||||
return !is_static_field_or_init(prop);
|
||||
});
|
||||
if (stat instanceof AST_Definitions) return (lexical || stat instanceof AST_Var) && declarations_only(stat);
|
||||
if (stat instanceof AST_ExportDeclaration) return is_declaration(stat.body, lexical);
|
||||
@@ -6651,7 +6662,7 @@ Compressor.prototype.compress = function(node) {
|
||||
if (prop.key instanceof AST_Node) prop.key.walk(tw);
|
||||
var value = prop.value;
|
||||
if (!value) return;
|
||||
if (prop instanceof AST_ClassField && prop.static) {
|
||||
if (is_static_field_or_init(prop)) {
|
||||
if (!used && value.contains_this()) used = true;
|
||||
walk_class_prop(value);
|
||||
} else {
|
||||
@@ -8595,16 +8606,20 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
def(AST_ClassExpression, function(compressor, first_in_statement) {
|
||||
var self = this;
|
||||
var exprs = [], values = [];
|
||||
var exprs = [], values = [], init = 0;
|
||||
var props = self.properties;
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var prop = props[i];
|
||||
if (prop.key instanceof AST_Node) exprs.push(prop.key);
|
||||
if (prop.static && prop.value
|
||||
&& prop instanceof AST_ClassField
|
||||
&& prop.value.has_side_effects(compressor)) {
|
||||
if (prop.value.contains_this()) return self;
|
||||
values.push(prop.value);
|
||||
if (!is_static_field_or_init(prop)) continue;
|
||||
var value = prop.value;
|
||||
if (!value.has_side_effects(compressor)) continue;
|
||||
if (value.contains_this()) return self;
|
||||
if (prop instanceof AST_ClassInit) {
|
||||
init++;
|
||||
values.push(prop);
|
||||
} else {
|
||||
values.push(value);
|
||||
}
|
||||
}
|
||||
var base = self.extends;
|
||||
@@ -8623,33 +8638,40 @@ Compressor.prototype.compress = function(node) {
|
||||
if (base || self.name || !compressor.has_directive("use strict")) {
|
||||
var node = to_class_expr(self);
|
||||
if (!base) node.extends = null;
|
||||
node.properties = [];
|
||||
if (values) {
|
||||
node.properties.push(make_node(AST_ClassField, self, {
|
||||
static: true,
|
||||
key: exprs.length ? make_sequence(self, exprs) : "c",
|
||||
value: make_sequence(self, values),
|
||||
}));
|
||||
} else if (exprs.length) {
|
||||
node.properties.push(make_node(AST_ClassMethod, self, {
|
||||
key: make_sequence(self, exprs),
|
||||
value: make_node(AST_Function, self, {
|
||||
argnames: [],
|
||||
body: [],
|
||||
}).init_vars(node),
|
||||
}));
|
||||
}
|
||||
node.properties = values ? values.length == init ? values : [ make_node(AST_ClassField, self, {
|
||||
static: true,
|
||||
key: exprs.length ? make_sequence(self, exprs) : "c",
|
||||
value: make_value(),
|
||||
}) ] : exprs.length ? [ make_node(AST_ClassMethod, self, {
|
||||
key: make_sequence(self, exprs),
|
||||
value: make_node(AST_Function, self, {
|
||||
argnames: [],
|
||||
body: [],
|
||||
}).init_vars(node),
|
||||
}) ] : [];
|
||||
return node;
|
||||
}
|
||||
if (values) exprs.push(make_node(AST_Call, self, {
|
||||
expression: make_node(AST_Arrow, self, {
|
||||
argnames: [],
|
||||
body: [],
|
||||
value: make_sequence(self, values),
|
||||
value: make_value(),
|
||||
}).init_vars(self.parent_scope),
|
||||
args: [],
|
||||
}));
|
||||
return make_sequence(self, exprs);
|
||||
|
||||
function make_value() {
|
||||
return make_sequence(self, values.map(function(node) {
|
||||
if (!(node instanceof AST_ClassInit)) return node;
|
||||
var fn = make_node(AST_Arrow, node, node.value);
|
||||
fn.argnames = [];
|
||||
return make_node(AST_Call, node, {
|
||||
expression: fn,
|
||||
args: [],
|
||||
});
|
||||
}));
|
||||
}
|
||||
});
|
||||
def(AST_Conditional, function(compressor) {
|
||||
var consequent = this.consequent.drop_side_effect_free(compressor);
|
||||
|
||||
Reference in New Issue
Block a user