Don't mangle exported symbols
This commit is contained in:
committed by
Richard van Velzen
parent
ce84a706a3
commit
0bc4f6edb4
10
lib/ast.js
10
lib/ast.js
@@ -745,6 +745,16 @@ var AST_Export = DEFNODE("Export", "exported_definition exported_value is_defaul
|
||||
exported_value: "[AST_Node?] An exported value",
|
||||
is_default: "[Boolean] Whether this is the default exported value of this module"
|
||||
},
|
||||
_walk: function (visitor) {
|
||||
visitor._visit(this, function () {
|
||||
if (this.exported_definition) {
|
||||
this.exported_definition._walk(visitor);
|
||||
}
|
||||
if (this.exported_value) {
|
||||
this.exported_value._walk(visitor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
|
||||
32
lib/scope.js
32
lib/scope.js
@@ -49,6 +49,7 @@ function SymbolDef(scope, index, orig) {
|
||||
this.scope = scope;
|
||||
this.references = [];
|
||||
this.global = false;
|
||||
this.export = false;
|
||||
this.mangled_name = null;
|
||||
this.object_destructuring_arg = false;
|
||||
this.undeclared = false;
|
||||
@@ -61,6 +62,7 @@ SymbolDef.prototype = {
|
||||
if (!options) options = {};
|
||||
|
||||
return (this.global && !options.toplevel)
|
||||
|| this.export
|
||||
|| this.object_destructuring_arg
|
||||
|| this.undeclared
|
||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
||||
@@ -102,6 +104,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
var defun = null;
|
||||
var nesting = 0;
|
||||
var in_destructuring = null;
|
||||
var in_export;
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (options.screw_ie8 && node instanceof AST_Catch) {
|
||||
var save_scope = scope;
|
||||
@@ -131,6 +134,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
labels = save_labels;
|
||||
return true; // don't descend again in TreeWalker
|
||||
}
|
||||
if (node instanceof AST_Export) {
|
||||
in_export = true;
|
||||
descend();
|
||||
in_export = false;
|
||||
}
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
var l = node.label;
|
||||
if (labels.has(l.name)) {
|
||||
@@ -151,14 +159,14 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
}
|
||||
if (node instanceof AST_SymbolFunarg) {
|
||||
node.object_destructuring_arg = !!in_destructuring;
|
||||
defun.def_variable(node);
|
||||
defun.def_variable(node, in_export);
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
node.thedef = node;
|
||||
node.references = [];
|
||||
}
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
defun.def_function(node);
|
||||
defun.def_function(node, in_export);
|
||||
}
|
||||
else if (node instanceof AST_SymbolDefun) {
|
||||
// Careful here, the scope where this should be defined is
|
||||
@@ -166,22 +174,22 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
// scope when we encounter the AST_Defun node (which is
|
||||
// instanceof AST_Scope) but we get to the symbol a bit
|
||||
// later.
|
||||
(node.scope = defun.parent_scope).def_function(node);
|
||||
(node.scope = defun.parent_scope).def_function(node, in_export);
|
||||
}
|
||||
else if (node instanceof AST_SymbolClass) {
|
||||
defun.def_variable(node);
|
||||
defun.def_variable(node, in_export);
|
||||
}
|
||||
else if (node instanceof AST_SymbolImport) {
|
||||
scope.def_variable(node);
|
||||
scope.def_variable(node, in_export);
|
||||
}
|
||||
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);
|
||||
(node.scope = defun.parent_scope).def_function(node, in_export);
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar
|
||||
|| node instanceof AST_SymbolConst) {
|
||||
var def = defun.def_variable(node);
|
||||
var def = defun.def_variable(node, in_export);
|
||||
def.constant = node instanceof AST_SymbolConst;
|
||||
def.destructuring = in_destructuring;
|
||||
def.init = tw.parent().value;
|
||||
@@ -294,11 +302,11 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol, in_export){
|
||||
this.functions.set(symbol.name, this.def_variable(symbol, in_export));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol, in_export){
|
||||
var def;
|
||||
if (!this.variables.has(symbol.name)) {
|
||||
def = new SymbolDef(this, this.variables.size(), symbol);
|
||||
@@ -311,6 +319,10 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
// TODO The real fix comes with block scoping being first class in uglifyJS,
|
||||
// enabling import definitions to behave like module-level let declarations
|
||||
}
|
||||
if (!this.parent_scope && in_export) {
|
||||
def.global = false;
|
||||
def.export = true;
|
||||
}
|
||||
} else {
|
||||
def = this.variables.get(symbol.name);
|
||||
def.orig.push(symbol);
|
||||
|
||||
@@ -350,6 +350,22 @@ import_statement_mangling: {
|
||||
}
|
||||
}
|
||||
|
||||
export_statement_mangling: {
|
||||
mangle = { };
|
||||
input: {
|
||||
export var foo = 6;
|
||||
export function bar() { }
|
||||
export class Baz { }
|
||||
bar(foo, Baz)
|
||||
}
|
||||
expect: {
|
||||
export var foo = 6;
|
||||
export function bar() { }
|
||||
export class Baz { }
|
||||
bar(foo, Baz)
|
||||
}
|
||||
}
|
||||
|
||||
// Fabio: My patches accidentally caused a crash whenever
|
||||
// there's an extraneous set of parens around an object.
|
||||
regression_cannot_destructure: {
|
||||
|
||||
Reference in New Issue
Block a user