replace single-use class definitions (#2524)

fixes #2416
This commit is contained in:
Alex Lam S.L
2017-11-28 20:57:15 +08:00
committed by GitHub
parent b84c99ef5c
commit 37cbd7080c
4 changed files with 44 additions and 12 deletions

View File

@@ -908,7 +908,7 @@ var AST_ConciseMethod = DEFNODE("ConciseMethod", "quote static is_generator asyn
$documentation: "An ES6 concise method inside an object or class" $documentation: "An ES6 concise method inside an object or class"
}, AST_ObjectProperty); }, AST_ObjectProperty);
var AST_Class = DEFNODE("Class", "name extends properties", { var AST_Class = DEFNODE("Class", "name extends properties inlined", {
$propdoc: { $propdoc: {
name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.", name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.",
extends: "[AST_Node]? optional parent class", extends: "[AST_Node]? optional parent class",

View File

@@ -329,6 +329,7 @@ merge(Compressor.prototype, {
value = node.fixed_value(); value = node.fixed_value();
if (value && ref_once(d) && !compressor.exposed(d)) { if (value && ref_once(d) && !compressor.exposed(d)) {
d.single_use = value instanceof AST_Lambda d.single_use = value instanceof AST_Lambda
|| value instanceof AST_Class
|| d.scope === node.scope && value.is_constant_expression(); || d.scope === node.scope && value.is_constant_expression();
} else { } else {
d.single_use = false; d.single_use = false;
@@ -386,7 +387,7 @@ merge(Compressor.prototype, {
} }
} }
} }
if (node instanceof AST_Defun) { if (node instanceof AST_DefClass || node instanceof AST_Defun) {
node.inlined = false; node.inlined = false;
var d = node.name.definition(); var d = node.name.definition();
if (compressor.exposed(d) || safe_to_read(d)) { if (compressor.exposed(d) || safe_to_read(d)) {
@@ -403,6 +404,13 @@ merge(Compressor.prototype, {
safe_ids = save_ids; safe_ids = save_ids;
return true; return true;
} }
if (node instanceof AST_ClassExpression) {
node.inlined = false;
push();
descend();
pop();
return true;
}
if (is_func_expr(node)) { if (is_func_expr(node)) {
node.inlined = false; node.inlined = false;
push(); push();
@@ -2385,9 +2393,8 @@ merge(Compressor.prototype, {
return false; return false;
return true; return true;
} }
def(AST_Node, return_false);
def(AST_Constant, return_true); function all_refs_local(scope) {
def(AST_Lambda, function(scope){
var self = this; var self = this;
var result = true; var result = true;
self.walk(new TreeWalker(function(node) { self.walk(new TreeWalker(function(node) {
@@ -2413,7 +2420,12 @@ merge(Compressor.prototype, {
} }
})); }));
return result; return result;
}); }
def(AST_Node, return_false);
def(AST_Constant, return_true);
def(AST_Class, all_refs_local);
def(AST_Lambda, all_refs_local);
def(AST_Unary, function(){ def(AST_Unary, function(){
return this.expression.is_constant_expression(); return this.expression.is_constant_expression();
}); });
@@ -4599,12 +4611,15 @@ merge(Compressor.prototype, {
&& is_lhs(self, compressor.parent()) !== self) { && is_lhs(self, compressor.parent()) !== self) {
var d = self.definition(); var d = self.definition();
var fixed = self.fixed_value(); var fixed = self.fixed_value();
if (fixed instanceof AST_DefClass) {
d.fixed = fixed = make_node(AST_ClassExpression, fixed, fixed);
}
if (fixed instanceof AST_Defun) { if (fixed instanceof AST_Defun) {
d.fixed = fixed = make_node(AST_Function, fixed, fixed); d.fixed = fixed = make_node(AST_Function, fixed, fixed);
} }
if (d.single_use && is_func_expr(fixed)) { if (d.single_use && (is_func_expr(fixed) || fixed instanceof AST_ClassExpression)) {
if (d.scope !== self.scope if (d.scope !== self.scope
&& (!compressor.option("reduce_funcs") && (!compressor.option("reduce_funcs") && is_func_expr(fixed)
|| d.escaped || d.escaped
|| fixed.inlined)) { || fixed.inlined)) {
d.single_use = false; d.single_use = false;

View File

@@ -4849,7 +4849,7 @@ issue_2496: {
new Foo("FAIL").run(); new Foo("FAIL").run();
} }
expect: { expect: {
class Foo { new class {
constructor(message) { constructor(message) {
this.message = message; this.message = message;
} }
@@ -4864,9 +4864,26 @@ issue_2496: {
this.go(); this.go();
}); });
} }
} }("FAIL").run();
new Foo("FAIL").run();
} }
expect_stdout: "PASS" expect_stdout: "PASS"
node_version: ">=6" node_version: ">=6"
} }
issue_2416: {
options = {
keep_classnames: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
class Foo {}
console.log(Foo.name);
}
expect: {
console.log((class Foo {}).name);
}
expect_stdout: "Foo"
node_version: ">=6"
}

View File

@@ -10,7 +10,7 @@ describe("spidermonkey export/import sanity test", function() {
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " + var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
uglifyjs + " -p spidermonkey -cm"; uglifyjs + " -p spidermonkey -cm";
exec(command, function(err, stdout) { exec(command, { maxBuffer: 1048576 }, function(err, stdout) {
if (err) throw err; if (err) throw err;
eval(stdout); eval(stdout);