aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-08-23 21:39:38 +0100
committerGitHub <noreply@github.com>2020-08-24 04:39:38 +0800
commit7dc61cdc895d055edfa9b1d82d17688ad3a57f1c (patch)
tree349b9016f337c058f28fd9ecb27b954a80758123
parentaf1b2f30c9904ba69aee5a6219215f1d0e64ad2b (diff)
downloadtracifyjs-7dc61cdc895d055edfa9b1d82d17688ad3a57f1c.tar.gz
tracifyjs-7dc61cdc895d055edfa9b1d82d17688ad3a57f1c.zip
tidy up various interfaces (#4066)
-rw-r--r--lib/ast.js12
-rw-r--r--lib/compress.js8
-rw-r--r--lib/output.js263
-rw-r--r--lib/propmangle.js2
-rw-r--r--lib/scope.js48
5 files changed, 167 insertions, 166 deletions
diff --git a/lib/ast.js b/lib/ast.js
index 2c27cbbe..b6d4ebb7 100644
--- a/lib/ast.js
+++ b/lib/ast.js
@@ -409,16 +409,16 @@ var AST_With = DEFNODE("With", "expression", {
/* -----[ scope and functions ]----- */
-var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", {
+var AST_Scope = DEFNODE("Scope", "cname enclosed uses_eval uses_with parent_scope functions variables make_def", {
$documentation: "Base class for all statements introducing a lexical scope",
$propdoc: {
- variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
- functions: "[Object/S] like `variables`, but only lists function declarations",
- uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
+ cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
+ enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
+ uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
parent_scope: "[AST_Scope?/S] link to the parent scope",
- enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
- cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
+ functions: "[Object/S] like `variables`, but only lists function declarations",
+ variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
},
clone: function(deep) {
var node = this._clone(deep);
diff --git a/lib/compress.js b/lib/compress.js
index bcaecb8a..3291f167 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -3152,11 +3152,11 @@ merge(Compressor.prototype, {
return this.expression._find_defs(compressor, "." + this.property + suffix);
});
def(AST_SymbolDeclaration, function(compressor) {
- if (!this.global()) return;
+ if (!this.definition().global) return;
if (HOP(compressor.option("global_defs"), this.name)) warn(this);
});
def(AST_SymbolRef, function(compressor, suffix) {
- if (!this.global()) return;
+ if (!this.definition().global) return;
var defines = compressor.option("global_defs");
var name = this.name + suffix;
if (HOP(defines, name)) return to_node(defines[name], this);
@@ -4700,7 +4700,7 @@ merge(Compressor.prototype, {
});
function log(sym, text, props) {
- AST_Node[sym.unreferenced() ? "warn" : "info"](text, props);
+ AST_Node[sym.definition().references.length > 0 ? "info" : "warn"](text, props);
}
function template(sym) {
@@ -6395,7 +6395,7 @@ merge(Compressor.prototype, {
}
}));
var code = OutputStream();
- AST_BlockStatement.prototype._codegen.call(fun, fun, code);
+ AST_BlockStatement.prototype._codegen.call(fun, code);
self.args = [
make_node(AST_String, self, {
value: fun.argnames.map(function(arg) {
diff --git a/lib/output.js b/lib/output.js
index 19c37b29..82610fb6 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -630,13 +630,7 @@ function OutputStream(options) {
var use_asm = false;
AST_Node.DEFMETHOD("print", function(stream, force_parens) {
- var self = this, generator = self._codegen;
- function doit() {
- stream.prepend_comments(self);
- self.add_source_map(stream);
- generator(self, stream);
- stream.append_comments(self);
- }
+ var self = this;
stream.push_node(self);
if (force_parens || self.needs_parens(stream)) {
stream.with_parens(doit);
@@ -644,9 +638,14 @@ function OutputStream(options) {
doit();
}
stream.pop_node();
- });
- AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
+ function doit() {
+ stream.prepend_comments(self);
+ self.add_source_map(stream);
+ self._codegen(stream);
+ stream.append_comments(self);
+ }
+ });
AST_Node.DEFMETHOD("print_to_string", function(options) {
var s = OutputStream(options);
this.print(s);
@@ -813,9 +812,9 @@ function OutputStream(options) {
/* -----[ PRINTERS ]----- */
- DEFPRINT(AST_Directive, function(self, output) {
- var quote = self.quote;
- var value = self.value;
+ DEFPRINT(AST_Directive, function(output) {
+ var quote = this.quote;
+ var value = this.value;
switch (output.option("quote_style")) {
case 0:
case 2:
@@ -828,7 +827,7 @@ function OutputStream(options) {
output.print(quote + value + quote);
output.semicolon();
});
- DEFPRINT(AST_Debugger, function(self, output) {
+ DEFPRINT(AST_Debugger, function(output) {
output.print("debugger");
output.semicolon();
});
@@ -864,21 +863,21 @@ function OutputStream(options) {
force_statement(this.body, output);
});
- DEFPRINT(AST_Statement, function(self, output) {
- self.body.print(output);
+ DEFPRINT(AST_Statement, function(output) {
+ this.body.print(output);
output.semicolon();
});
- DEFPRINT(AST_Toplevel, function(self, output) {
- display_body(self.body, true, output, true);
+ DEFPRINT(AST_Toplevel, function(output) {
+ display_body(this.body, true, output, true);
output.print("");
});
- DEFPRINT(AST_LabeledStatement, function(self, output) {
- self.label.print(output);
+ DEFPRINT(AST_LabeledStatement, function(output) {
+ this.label.print(output);
output.colon();
- self.body.print(output);
+ this.body.print(output);
});
- DEFPRINT(AST_SimpleStatement, function(self, output) {
- self.body.print(output);
+ DEFPRINT(AST_SimpleStatement, function(output) {
+ this.body.print(output);
output.semicolon();
});
function print_braced_empty(self, output) {
@@ -895,13 +894,14 @@ function OutputStream(options) {
});
} else print_braced_empty(self, output);
}
- DEFPRINT(AST_BlockStatement, function(self, output) {
- print_braced(self, output);
+ DEFPRINT(AST_BlockStatement, function(output) {
+ print_braced(this, output);
});
- DEFPRINT(AST_EmptyStatement, function(self, output) {
+ DEFPRINT(AST_EmptyStatement, function(output) {
output.semicolon();
});
- DEFPRINT(AST_Do, function(self, output) {
+ DEFPRINT(AST_Do, function(output) {
+ var self = this;
output.print("do");
output.space();
make_block(self.body, output);
@@ -913,7 +913,8 @@ function OutputStream(options) {
});
output.semicolon();
});
- DEFPRINT(AST_While, function(self, output) {
+ DEFPRINT(AST_While, function(output) {
+ var self = this;
output.print("while");
output.space();
output.with_parens(function() {
@@ -922,7 +923,8 @@ function OutputStream(options) {
output.space();
self._do_print_body(output);
});
- DEFPRINT(AST_For, function(self, output) {
+ DEFPRINT(AST_For, function(output) {
+ var self = this;
output.print("for");
output.space();
output.with_parens(function() {
@@ -951,7 +953,8 @@ function OutputStream(options) {
output.space();
self._do_print_body(output);
});
- DEFPRINT(AST_ForIn, function(self, output) {
+ DEFPRINT(AST_ForIn, function(output) {
+ var self = this;
output.print("for");
output.space();
output.with_parens(function() {
@@ -964,7 +967,8 @@ function OutputStream(options) {
output.space();
self._do_print_body(output);
});
- DEFPRINT(AST_With, function(self, output) {
+ DEFPRINT(AST_With, function(output) {
+ var self = this;
output.print("with");
output.space();
output.with_parens(function() {
@@ -975,7 +979,7 @@ function OutputStream(options) {
});
/* -----[ functions ]----- */
- AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) {
+ DEFPRINT(AST_Lambda, function(output, nokeyword) {
var self = this;
if (!nokeyword) {
output.print("function");
@@ -993,32 +997,23 @@ function OutputStream(options) {
output.space();
print_braced(self, output, true);
});
- DEFPRINT(AST_Lambda, function(self, output) {
- self._do_print(output);
- });
/* -----[ jumps ]----- */
- function print_jump(output, kind, target) {
- output.print(kind);
- if (target) {
- output.space();
- target.print(output);
- }
- output.semicolon();
+ function print_jump(kind, prop) {
+ return function(output) {
+ output.print(kind);
+ var target = this[prop];
+ if (target) {
+ output.space();
+ target.print(output);
+ }
+ output.semicolon();
+ };
}
-
- DEFPRINT(AST_Return, function(self, output) {
- print_jump(output, "return", self.value);
- });
- DEFPRINT(AST_Throw, function(self, output) {
- print_jump(output, "throw", self.value);
- });
- DEFPRINT(AST_Break, function(self, output) {
- print_jump(output, "break", self.label);
- });
- DEFPRINT(AST_Continue, function(self, output) {
- print_jump(output, "continue", self.label);
- });
+ DEFPRINT(AST_Return, print_jump("return", "value"));
+ DEFPRINT(AST_Throw, print_jump("throw", "value"));
+ DEFPRINT(AST_Break, print_jump("break", "label"));
+ DEFPRINT(AST_Continue, print_jump("continue", "label"));
/* -----[ if ]----- */
function make_then(self, output) {
@@ -1047,7 +1042,8 @@ function OutputStream(options) {
}
force_statement(self.body, output);
}
- DEFPRINT(AST_If, function(self, output) {
+ DEFPRINT(AST_If, function(output) {
+ var self = this;
output.print("if");
output.space();
output.with_parens(function() {
@@ -1069,7 +1065,8 @@ function OutputStream(options) {
});
/* -----[ switch ]----- */
- DEFPRINT(AST_Switch, function(self, output) {
+ DEFPRINT(AST_Switch, function(output) {
+ var self = this;
output.print("switch");
output.space();
output.with_parens(function() {
@@ -1087,28 +1084,30 @@ function OutputStream(options) {
});
});
});
- AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) {
+ function print_branch_body(self, output) {
output.newline();
- this.body.forEach(function(stmt) {
+ self.body.forEach(function(stmt) {
output.indent();
stmt.print(output);
output.newline();
});
- });
- DEFPRINT(AST_Default, function(self, output) {
+ }
+ DEFPRINT(AST_Default, function(output) {
output.print("default:");
- self._do_print_body(output);
+ print_branch_body(this, output);
});
- DEFPRINT(AST_Case, function(self, output) {
+ DEFPRINT(AST_Case, function(output) {
+ var self = this;
output.print("case");
output.space();
self.expression.print(output);
output.print(":");
- self._do_print_body(output);
+ print_branch_body(self, output);
});
/* -----[ exceptions ]----- */
- DEFPRINT(AST_Try, function(self, output) {
+ DEFPRINT(AST_Try, function(output) {
+ var self = this;
output.print("try");
output.space();
print_braced(self, output);
@@ -1121,7 +1120,8 @@ function OutputStream(options) {
self.bfinally.print(output);
}
});
- DEFPRINT(AST_Catch, function(self, output) {
+ DEFPRINT(AST_Catch, function(output) {
+ var self = this;
output.print("catch");
output.space();
output.with_parens(function() {
@@ -1130,13 +1130,14 @@ function OutputStream(options) {
output.space();
print_braced(self, output);
});
- DEFPRINT(AST_Finally, function(self, output) {
+ DEFPRINT(AST_Finally, function(output) {
output.print("finally");
output.space();
- print_braced(self, output);
+ print_braced(this, output);
});
- DEFPRINT(AST_Var, function(self, output) {
+ DEFPRINT(AST_Var, function(output) {
+ var self = this;
output.print("var");
output.space();
self.definitions.forEach(function(def, i) {
@@ -1161,7 +1162,8 @@ function OutputStream(options) {
node.print(output, parens);
}
- DEFPRINT(AST_VarDef, function(self, output) {
+ DEFPRINT(AST_VarDef, function(output) {
+ var self = this;
self.name.print(output);
if (self.value) {
output.space();
@@ -1185,18 +1187,19 @@ function OutputStream(options) {
});
});
}
- DEFPRINT(AST_Call, function(self, output) {
- self.expression.print(output);
- print_call_args(self, output);
+ DEFPRINT(AST_Call, function(output) {
+ this.expression.print(output);
+ print_call_args(this, output);
});
- DEFPRINT(AST_New, function(self, output) {
+ DEFPRINT(AST_New, function(output) {
+ var self = this;
output.print("new");
output.space();
self.expression.print(output);
if (need_constructor_parens(self, output)) print_call_args(self, output);
});
- DEFPRINT(AST_Sequence, function(self, output) {
- self.expressions.forEach(function(node, index) {
+ DEFPRINT(AST_Sequence, function(output) {
+ this.expressions.forEach(function(node, index) {
if (index > 0) {
output.comma();
if (output.should_break()) {
@@ -1207,7 +1210,8 @@ function OutputStream(options) {
node.print(output);
});
});
- DEFPRINT(AST_Dot, function(self, output) {
+ DEFPRINT(AST_Dot, function(output) {
+ var self = this;
var expr = self.expression;
expr.print(output);
var prop = self.property;
@@ -1228,35 +1232,38 @@ function OutputStream(options) {
output.print_name(prop);
}
});
- DEFPRINT(AST_Sub, function(self, output) {
- self.expression.print(output);
+ DEFPRINT(AST_Sub, function(output) {
+ this.expression.print(output);
output.print("[");
- self.property.print(output);
+ this.property.print(output);
output.print("]");
});
- DEFPRINT(AST_UnaryPrefix, function(self, output) {
- var op = self.operator;
+ DEFPRINT(AST_UnaryPrefix, function(output) {
+ var op = this.operator;
+ var exp = this.expression;
output.print(op);
if (/^[a-z]/i.test(op)
|| (/[+-]$/.test(op)
- && self.expression instanceof AST_UnaryPrefix
- && /^[+-]/.test(self.expression.operator))) {
+ && exp instanceof AST_UnaryPrefix
+ && /^[+-]/.test(exp.operator))) {
output.space();
}
- self.expression.print(output);
+ exp.print(output);
});
- DEFPRINT(AST_UnaryPostfix, function(self, output) {
- self.expression.print(output);
- output.print(self.operator);
+ DEFPRINT(AST_UnaryPostfix, function(output) {
+ this.expression.print(output);
+ output.print(this.operator);
});
- DEFPRINT(AST_Binary, function(self, output) {
+ DEFPRINT(AST_Binary, function(output) {
+ var self = this;
self.left.print(output);
output.space();
output.print(self.operator);
output.space();
self.right.print(output);
});
- DEFPRINT(AST_Conditional, function(self, output) {
+ DEFPRINT(AST_Conditional, function(output) {
+ var self = this;
self.condition.print(output);
output.space();
output.print("?");
@@ -1268,10 +1275,10 @@ function OutputStream(options) {
});
/* -----[ literals ]----- */
- DEFPRINT(AST_Array, function(self, output) {
- output.with_square(function() {
- var a = self.elements, len = a.length;
- if (len > 0) output.space();
+ DEFPRINT(AST_Array, function(output) {
+ var a = this.elements, len = a.length;
+ output.with_square(len > 0 ? function() {
+ output.space();
a.forEach(function(exp, i) {
if (i) output.comma();
exp.print(output);
@@ -1281,12 +1288,13 @@ function OutputStream(options) {
if (i === len - 1 && exp instanceof AST_Hole)
output.comma();
});
- if (len > 0) output.space();
- });
+ output.space();
+ } : noop);
});
- DEFPRINT(AST_Object, function(self, output) {
- if (self.properties.length > 0) output.with_block(function() {
- self.properties.forEach(function(prop, i) {
+ DEFPRINT(AST_Object, function(output) {
+ var props = this.properties;
+ if (props.length > 0) output.with_block(function() {
+ props.forEach(function(prop, i) {
if (i) {
output.print(",");
output.newline();
@@ -1296,7 +1304,7 @@ function OutputStream(options) {
});
output.newline();
});
- else print_braced_empty(self, output);
+ else print_braced_empty(this, output);
});
function print_property_name(key, quote, output) {
@@ -1315,47 +1323,48 @@ function OutputStream(options) {
}
}
- DEFPRINT(AST_ObjectKeyVal, function(self, output) {
+ DEFPRINT(AST_ObjectKeyVal, function(output) {
+ var self = this;
print_property_name(self.key, self.quote, output);
output.colon();
self.value.print(output);
});
- AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, output) {
- output.print(type);
- output.space();
- print_property_name(this.key.name, this.quote, output);
- this.value._do_print(output, true);
- });
- DEFPRINT(AST_ObjectSetter, function(self, output) {
- self._print_getter_setter("set", output);
- });
- DEFPRINT(AST_ObjectGetter, function(self, output) {
- self._print_getter_setter("get", output);
- });
- DEFPRINT(AST_Symbol, function(self, output) {
- var def = self.definition();
- output.print_name(def && def.mangled_name || self.name);
+ function print_accessor(type) {
+ return function(output) {
+ var self = this;
+ output.print(type);
+ output.space();
+ print_property_name(self.key.name, self.quote, output);
+ self.value._codegen(output, true);
+ };
+ }
+ DEFPRINT(AST_ObjectGetter, print_accessor("get"));
+ DEFPRINT(AST_ObjectSetter, print_accessor("set"));
+ DEFPRINT(AST_Symbol, function(output) {
+ var def = this.definition();
+ output.print_name(def && def.mangled_name || this.name);
});
DEFPRINT(AST_Hole, noop);
- DEFPRINT(AST_This, function(self, output) {
+ DEFPRINT(AST_This, function(output) {
output.print("this");
});
- DEFPRINT(AST_Constant, function(self, output) {
- output.print(self.value);
+ DEFPRINT(AST_Constant, function(output) {
+ output.print(this.value);
});
- DEFPRINT(AST_String, function(self, output) {
- output.print_string(self.value, self.quote);
+ DEFPRINT(AST_String, function(output) {
+ output.print_string(this.value, this.quote);
});
- DEFPRINT(AST_Number, function(self, output) {
- if (use_asm && self.start && self.start.raw != null) {
- output.print(self.start.raw);
+ DEFPRINT(AST_Number, function(output) {
+ var start = this.start;
+ if (use_asm && start && start.raw != null) {
+ output.print(start.raw);
} else {
- output.print(make_num(self.value));
+ output.print(make_num(this.value));
}
});
- DEFPRINT(AST_RegExp, function(self, output) {
- var regexp = self.value;
+ DEFPRINT(AST_RegExp, function(output) {
+ var regexp = this.value;
var str = regexp.toString();
var end = str.lastIndexOf("/");
if (regexp.raw_source) {
@@ -1389,7 +1398,7 @@ function OutputStream(options) {
}
}));
var p = output.parent();
- if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
+ if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === this)
output.print(" ");
});
diff --git a/lib/propmangle.js b/lib/propmangle.js
index 04194393..e47497de 100644
--- a/lib/propmangle.js
+++ b/lib/propmangle.js
@@ -110,7 +110,6 @@ function mangle_properties(ast, options) {
cache: null,
debug: false,
keep_quoted: false,
- only_cache: false,
regex: null,
reserved: null,
}, true);
@@ -213,7 +212,6 @@ function mangle_properties(ast, options) {
function can_mangle(name) {
if (unmangleable[name]) return false;
- if (options.only_cache) return cache.has(name);
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
return true;
}
diff --git a/lib/scope.js b/lib/scope.js
index 450c1062..5d990c06 100644
--- a/lib/scope.js
+++ b/lib/scope.js
@@ -96,8 +96,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
// pass 1: setup scope chaining and handle definitions
var self = this;
- var scope = self.parent_scope = null;
var defun = null;
+ var next_def_id = 0;
+ var scope = self.parent_scope = null;
var tw = new TreeWalker(function(node, descend) {
if (node instanceof AST_Catch) {
var save_scope = scope;
@@ -149,7 +150,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
scope.def_variable(node).defun = defun;
}
});
- self.next_def_id = 0;
+ self.make_def = function(orig, init) {
+ return new SymbolDef(++next_def_id, this, orig, init);
+ };
self.walk(tw);
// pass 2: find back references and eval
@@ -240,12 +243,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
}
});
-AST_Scope.DEFMETHOD("make_def", function(orig, init) {
- var top = this;
- while (top.parent_scope) top = top.parent_scope;
- return new SymbolDef(++top.next_def_id, this, orig, init);
-});
-
AST_Toplevel.DEFMETHOD("def_global", function(node) {
var globals = this.globals, name = node.name;
if (globals.has(name)) {
@@ -259,23 +256,28 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
}
});
+function init_scope_vars(scope, parent) {
+ scope.cname = -1; // the current index for mangling functions/variables
+ scope.enclosed = []; // variables from this or outer scope(s) that are referenced from this or inner scopes
+ scope.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
+ scope.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
+ scope.parent_scope = parent; // the parent scope (null if this is the top level)
+ scope.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
+ scope.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
+ if (parent) scope.make_def = parent.make_def; // top-level tracking of SymbolDef instances
+}
+
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
- this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
- this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
- this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
- this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
- this.parent_scope = parent_scope; // the parent scope
- this.enclosed = []; // a list of variables from this or outer scope(s) that are referenced from this or inner scopes
- this.cname = -1; // the current index for mangling functions/variables
+ init_scope_vars(this, parent_scope);
});
-AST_Lambda.DEFMETHOD("init_scope_vars", function() {
- AST_Scope.prototype.init_scope_vars.apply(this, arguments);
+AST_Lambda.DEFMETHOD("init_scope_vars", function(parent_scope) {
+ init_scope_vars(this, parent_scope);
this.uses_arguments = false;
this.def_variable(new AST_SymbolFunarg({
name: "arguments",
start: this.start,
- end: this.end
+ end: this.end,
}));
});
@@ -387,18 +389,10 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options) {
// labels are always mangleable
AST_Label.DEFMETHOD("unmangleable", return_false);
-AST_Symbol.DEFMETHOD("unreferenced", function() {
- return !this.definition().references.length && !this.scope.pinned();
-});
-
AST_Symbol.DEFMETHOD("definition", function() {
return this.thedef;
});
-AST_Symbol.DEFMETHOD("global", function() {
- return this.definition().global;
-});
-
function _default_mangler_options(options) {
options = defaults(options, {
eval : false,
@@ -558,8 +552,8 @@ AST_Sequence.DEFMETHOD("tail_node", function() {
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
options = _default_mangler_options(options);
base54.reset();
+ var fn = AST_Symbol.prototype.add_source_map;
try {
- var fn = AST_Symbol.prototype.add_source_map;
AST_Symbol.prototype.add_source_map = function() {
if (!this.unmangleable(options)) base54.consider(this.name, -1);
};