diff --git a/lib/scope.js b/lib/scope.js index ccb836e7..72503205 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -112,7 +112,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ var defun = null; var in_destructuring = null; var in_export = false; - var in_block = 0; var for_scopes = []; var tw = new TreeWalker(function(node, descend){ if (node.is_block_scope()) { @@ -158,16 +157,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ in_export = false; return true; } - if (node instanceof AST_BlockStatement - || node instanceof AST_Switch - || node instanceof AST_Try - || node instanceof AST_Catch - || node instanceof AST_Finally) { - in_block++; - descend(); - in_block--; - return true; - } if (node instanceof AST_LabeledStatement) { var l = node.label; if (labels.has(l.name)) { @@ -194,7 +183,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ node.references = []; } if (node instanceof AST_SymbolLambda) { - defun.def_function(node, in_export, in_block); + mark_export(defun.def_function(node)); } else if (node instanceof AST_SymbolDefun) { // Careful here, the scope where this should be defined is @@ -206,23 +195,23 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ while (parent_lambda.is_block_scope()) { parent_lambda = parent_lambda.parent_scope; } - (node.scope = parent_lambda).def_function(node, in_export, in_block); + mark_export((node.scope = parent_lambda).def_function(node)); } else if (node instanceof AST_SymbolClass) { - defun.def_variable(node, in_export, in_block); + mark_export(defun.def_variable(node)); } else if (node instanceof AST_SymbolImport) { - scope.def_variable(node, in_export, in_block); + mark_export(scope.def_variable(node)); } else if (node instanceof AST_SymbolDefClass) { // This deals with the name of the class being available // inside the class. - (node.scope = defun.parent_scope).def_function(node, in_export, in_block); + mark_export((node.scope = defun.parent_scope).def_function(node)); } else if (node instanceof AST_SymbolVar || node instanceof AST_SymbolLet || node instanceof AST_SymbolConst) { - var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node, in_export, in_block); + var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node); def.destructuring = in_destructuring; if (defun !== scope) { node.mark_enclosed(options); @@ -234,7 +223,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ } } else if (node instanceof AST_SymbolCatch) { - scope.def_variable(node, in_export, in_block).defun = defun; + scope.def_variable(node).defun = defun; } else if (node instanceof AST_LabelRef) { var sym = labels.get(node.name); @@ -245,12 +234,18 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ })); node.thedef = sym; } + + function mark_export(def) { + if (in_export) { + def.export = true; + in_export = false; + } + } }); self.walk(tw); // pass 2: find back references and eval var func = null; - var cls = null; var globals = self.globals = new Dictionary(); var tw = new TreeWalker(function(node, descend){ if (node instanceof AST_Lambda) { @@ -260,13 +255,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ func = prev_func; return true; } - if (node instanceof AST_Class) { - var prev_cls = cls; - cls = node; - descend(); - cls = prev_cls; - return true; - } if (node instanceof AST_LoopControl && node.label) { node.label.thedef.references.push(node); return true; @@ -351,22 +339,13 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){ this.cname = -1; // the current index for mangling functions/variables }); -AST_Node.DEFMETHOD("is_block_scope", function(){ - return false; // Behaviour will be overridden by AST_Block -}); - -AST_Block.DEFMETHOD("is_block_scope", function(){ - return ( - !(this instanceof AST_Lambda) && - !(this instanceof AST_Toplevel) && - !(this instanceof AST_Class) && - !(this instanceof AST_SwitchBranch) - ); -}); - -AST_IterationStatement.DEFMETHOD("is_block_scope", function(){ - return true; -}); +AST_Node.DEFMETHOD("is_block_scope", return_false); +AST_Class.DEFMETHOD("is_block_scope", return_false); +AST_Lambda.DEFMETHOD("is_block_scope", return_false); +AST_Toplevel.DEFMETHOD("is_block_scope", return_false); +AST_SwitchBranch.DEFMETHOD("is_block_scope", return_false); +AST_Block.DEFMETHOD("is_block_scope", return_true); +AST_IterationStatement.DEFMETHOD("is_block_scope", return_true); AST_Lambda.DEFMETHOD("init_scope_vars", function(){ AST_Scope.prototype.init_scope_vars.apply(this, arguments); @@ -404,24 +383,19 @@ AST_Scope.DEFMETHOD("find_variable", function(name){ || (this.parent_scope && this.parent_scope.find_variable(name)); }); -AST_Scope.DEFMETHOD("def_function", function(symbol, in_export, in_block){ - this.functions.set(symbol.name, this.def_variable(symbol, in_export, in_block)); +AST_Scope.DEFMETHOD("def_function", function(symbol){ + var def = this.def_variable(symbol); + this.functions.set(symbol.name, def); + return def; }); -AST_Scope.DEFMETHOD("def_variable", function(symbol, in_export, in_block){ +AST_Scope.DEFMETHOD("def_variable", function(symbol){ var def; if (!this.variables.has(symbol.name)) { def = new SymbolDef(this, this.variables.size(), symbol); this.variables.set(symbol.name, def); def.object_destructuring_arg = symbol.object_destructuring_arg; - if (in_export) { - def.export = true; - } - if (in_block && symbol instanceof AST_SymbolBlockDeclaration) { - def.global = false; - } else { - def.global = !this.parent_scope; - } + def.global = !this.parent_scope; } else { def = this.variables.get(symbol.name); def.orig.push(symbol); diff --git a/test/compress/issue-2001.js b/test/compress/issue-2001.js index 4efa8261..a6efcb5b 100644 --- a/test/compress/issue-2001.js +++ b/test/compress/issue-2001.js @@ -61,3 +61,61 @@ export_default_func_3: { } expect_exact: "export default function(){};" } + +export_mangle_1: { + mangle = {} + input: { + export function foo(one, two) { + return one - two; + }; + } + expect_exact: "export function foo(n,o){return n-o};" +} + +export_mangle_2: { + mangle = {} + input: { + export default function foo(one, two) { + return one - two; + }; + } + expect_exact: "export default function foo(n,o){return n-o};" +} + +export_mangle_3: { + mangle = {} + input: { + export class C { + go(one, two) { + var z = one; + return one - two + z; + } + }; + } + expect_exact: "export class C{go(n,r){var t=n;return n-r+t}};" +} + +export_mangle_4: { + mangle = {} + input: { + export default class C { + go(one, two) { + var z = one; + return one - two + z; + } + }; + } + expect_exact: "export default class C{go(n,r){var t=n;return n-r+t}};" +} + +export_mangle_5: { + mangle = {} + input: { + export default { + prop: function(one, two) { + return one - two; + } + }; + } + expect_exact: "export default{prop:function(n,r){return n-r}};" +}