fix export default
- prohibit definition statements - parse `AST_Defun` properly - drop only unused class and function names
This commit is contained in:
parent
e5d93f1555
commit
e793f9b159
|
|
@ -2021,7 +2021,7 @@ merge(Compressor.prototype, {
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (node !== self) {
|
if (node !== self) {
|
||||||
if (node instanceof AST_Defun || node instanceof AST_DefClass) {
|
if (node instanceof AST_Defun || node instanceof AST_DefClass) {
|
||||||
if ((!drop_funcs || tw.parent() instanceof AST_Export) && scope === self) {
|
if (!drop_funcs && scope === self) {
|
||||||
var node_def = node.name.definition();
|
var node_def = node.name.definition();
|
||||||
if (node_def.global && !(node_def.id in in_use_ids)) {
|
if (node_def.global && !(node_def.id in in_use_ids)) {
|
||||||
in_use_ids[node_def.id] = true;
|
in_use_ids[node_def.id] = true;
|
||||||
|
|
@ -2157,9 +2157,11 @@ merge(Compressor.prototype, {
|
||||||
// pass 3: we should drop declarations not in_use
|
// pass 3: we should drop declarations not in_use
|
||||||
var tt = new TreeTransformer(
|
var tt = new TreeTransformer(
|
||||||
function before(node, descend, in_list) {
|
function before(node, descend, in_list) {
|
||||||
if (node instanceof AST_Function
|
var parent = tt.parent();
|
||||||
&& node.name
|
if (!compressor.option("keep_fnames")
|
||||||
&& !compressor.option("keep_fnames")) {
|
&& ((node instanceof AST_Function || node instanceof AST_ClassExpression) && node.name
|
||||||
|
|| (node instanceof AST_Defun || node instanceof AST_DefClass)
|
||||||
|
&& parent instanceof AST_Export && parent.is_default)) {
|
||||||
var def = node.name.definition();
|
var def = node.name.definition();
|
||||||
// any declarations with same name will overshadow
|
// any declarations with same name will overshadow
|
||||||
// name of this anonymous function and can therefore
|
// name of this anonymous function and can therefore
|
||||||
|
|
@ -2194,7 +2196,7 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((node instanceof AST_Defun || node instanceof AST_DefClass) && node !== self) {
|
if ((node instanceof AST_Defun || node instanceof AST_DefClass) && !(parent instanceof AST_Export) && node !== self) {
|
||||||
var keep = (node.name.definition().id in in_use_ids) || !drop_funcs && node.name.definition().global;
|
var keep = (node.name.definition().id in in_use_ids) || !drop_funcs && node.name.definition().global;
|
||||||
if (!keep) {
|
if (!keep) {
|
||||||
compressor[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", template(node.name));
|
compressor[node.name.unreferenced() ? "warn" : "info"]("Dropping unused function {name} [{file}:{line},{col}]", template(node.name));
|
||||||
|
|
@ -2202,7 +2204,7 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Definitions && !(tt.parent() instanceof AST_ForIn && tt.parent().init === node)) {
|
if (node instanceof AST_Definitions && !(parent instanceof AST_ForIn && parent.init === node)) {
|
||||||
// place uninitialized names at the start
|
// place uninitialized names at the start
|
||||||
var body = [], head = [], tail = [];
|
var body = [], head = [], tail = [];
|
||||||
// for unused names whose initialization has
|
// for unused names whose initialization has
|
||||||
|
|
@ -2298,7 +2300,7 @@ merge(Compressor.prototype, {
|
||||||
if (!(def.id in in_use_ids)
|
if (!(def.id in in_use_ids)
|
||||||
&& (drop_vars || !def.global)
|
&& (drop_vars || !def.global)
|
||||||
&& self.variables.get(def.name) === def) {
|
&& self.variables.get(def.name) === def) {
|
||||||
return maintain_this_binding(tt.parent(), node, node.right.transform(tt));
|
return maintain_this_binding(parent, node, node.right.transform(tt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// certain combination of unused name + side effect leads to:
|
// certain combination of unused name + side effect leads to:
|
||||||
|
|
|
||||||
22
lib/parse.js
22
lib/parse.js
|
|
@ -2417,14 +2417,26 @@ function parse($TEXT, options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var is_definition = is("keyword", "var")
|
var is_definition = is("keyword", "var") || is("keyword", "let") || is("keyword", "const");
|
||||||
|| is("keyword", "let")
|
|
||||||
|| is("keyword", "const")
|
|
||||||
|| is("keyword", "function") && !is_default;
|
|
||||||
if (is_definition) {
|
if (is_definition) {
|
||||||
|
if (is_default) unexpected();
|
||||||
exported_definition = statement();
|
exported_definition = statement();
|
||||||
|
} else if (is("keyword", "class")) {
|
||||||
|
var cls = expr_atom(false);
|
||||||
|
if (cls.name) {
|
||||||
|
cls.name = new AST_SymbolDefClass(cls.name);
|
||||||
|
exported_definition = new AST_DefClass(cls);
|
||||||
|
} else {
|
||||||
|
exported_value = cls;
|
||||||
|
}
|
||||||
} else if (is("keyword", "function")) {
|
} else if (is("keyword", "function")) {
|
||||||
exported_value = expr_atom(false);
|
var func = expr_atom(false);
|
||||||
|
if (func.name) {
|
||||||
|
func.name = new AST_SymbolDefun(func.name);
|
||||||
|
exported_definition = new AST_Defun(func);
|
||||||
|
} else {
|
||||||
|
exported_value = func;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
exported_value = expression(false);
|
exported_value = expression(false);
|
||||||
semicolon();
|
semicolon();
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||||
}
|
}
|
||||||
|
|
||||||
function mark_export(def, level) {
|
function mark_export(def, level) {
|
||||||
def.export = tw.parent(level) instanceof AST_Export;
|
var node = tw.parent(level);
|
||||||
|
def.export = node instanceof AST_Export && !node.is_default;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
export_func_1: {
|
export_func_1: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: true,
|
hoist_funs: true,
|
||||||
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -13,6 +14,7 @@ export_func_2: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: true,
|
hoist_funs: true,
|
||||||
side_effects: false,
|
side_effects: false,
|
||||||
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -25,6 +27,7 @@ export_func_3: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: true,
|
hoist_funs: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -36,6 +39,7 @@ export_func_3: {
|
||||||
export_default_func_1: {
|
export_default_func_1: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: true,
|
hoist_funs: true,
|
||||||
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -48,6 +52,7 @@ export_default_func_2: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: true,
|
hoist_funs: true,
|
||||||
side_effects: false,
|
side_effects: false,
|
||||||
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -60,6 +65,7 @@ export_default_func_3: {
|
||||||
options = {
|
options = {
|
||||||
hoist_funs: true,
|
hoist_funs: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -68,6 +74,82 @@ export_default_func_3: {
|
||||||
expect_exact: "export default function(){};"
|
expect_exact: "export default function(){};"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export_class_1: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export class C {};
|
||||||
|
}
|
||||||
|
expect_exact: "export class C{};"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_class_2: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
side_effects: false,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export class C {}(1);
|
||||||
|
}
|
||||||
|
expect_exact: "export class C{};1;"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_class_3: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export class C {}(1);
|
||||||
|
}
|
||||||
|
expect_exact: "export class C{};"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_default_class_1: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default class C {};
|
||||||
|
}
|
||||||
|
expect_exact: "export default class{};"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_default_class_2: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
side_effects: false,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default class C {}(1);
|
||||||
|
}
|
||||||
|
expect_exact: "export default class{};1;"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_default_class_3: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default class C {}(1);
|
||||||
|
}
|
||||||
|
expect_exact: "export default class{};"
|
||||||
|
}
|
||||||
|
|
||||||
export_mangle_1: {
|
export_mangle_1: {
|
||||||
mangle = {
|
mangle = {
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
|
|
@ -89,7 +171,7 @@ export_mangle_2: {
|
||||||
return one - two;
|
return one - two;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export default function n(r,t){return r-t};"
|
expect_exact: "export default function n(n,r){return n-r};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_3: {
|
export_mangle_3: {
|
||||||
|
|
@ -125,7 +207,7 @@ export_mangle_4: {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect_exact: "export default class C{go(n,r){return n-r+n}};"
|
expect_exact: "export default class n{go(n,r){return n-r+n}};"
|
||||||
}
|
}
|
||||||
|
|
||||||
export_mangle_5: {
|
export_mangle_5: {
|
||||||
|
|
@ -181,6 +263,19 @@ export_toplevel_2: {
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
export class B {};
|
export class B {};
|
||||||
export default class C {};
|
export default class {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export_default_func_ref: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default function f(){};
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "export default function f(){};f();"
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user