From ea892ef28cc851f38f232fdb21a5283c19bda00c Mon Sep 17 00:00:00 2001 From: Onoshko Dan Date: Thu, 17 Apr 2014 23:21:45 +0700 Subject: [PATCH] Refactoring over! --- lib/ast.js | 6 +- lib/compress.js | 27 +-- lib/index.html | 10 +- lib/output.js | 525 ++++++++++++++++++++++------------------------- lib/scope.js | 79 +++---- lib/sourcemap.js | 62 +++--- lib/transform.js | 5 +- lib/translate.js | 11 +- 8 files changed, 354 insertions(+), 371 deletions(-) diff --git a/lib/ast.js b/lib/ast.js index 51ed69c3..39bf250c 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -288,7 +288,7 @@ Cola.AST_Scope = Cola.DEFNODE("Scope", "directives variables functions uses_with }, }, Cola.AST_Block); -Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals", { +Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals language", { $documentation: "The toplevel scope", $propdoc: { globals: "[Object/S] a map of name -> SymbolDef for all undeclared names", @@ -307,7 +307,7 @@ Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals", { var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")"; wrapped_tl = Cola.parse(wrapped_tl); - wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){ + wrapped_tl = wrapped_tl.transform(new Cola.TreeTransformer(function before(node){ if (node instanceof Cola.AST_Directive && node.value == "$ORIG") { return Cola.MAP.splice(self.body); } @@ -328,7 +328,7 @@ Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals", { } var wrapped_tl = "(function(exports, global){ global['" + name + "'] = exports; '$ORIG'; '$EXPORTS'; }({}, (function(){return this}())))"; wrapped_tl = Cola.parse(wrapped_tl); - wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){ + wrapped_tl = wrapped_tl.transform(new Cola.TreeTransformer(function before(node){ if (node instanceof Cola.AST_SimpleStatement) { node = node.body; if (node instanceof Cola.AST_String) switch (node.getValue()) { diff --git a/lib/compress.js b/lib/compress.js index c94d2436..479b0f8e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -42,11 +42,12 @@ ***********************************************************************/ "use strict"; +!window.Cola && (window.Cola = {}); -function Compressor(options, false_by_default) { - if (!(this instanceof Compressor)) - return new Compressor(options, false_by_default); - TreeTransformer.call(this, this.before, this.after); +Cola.Compressor = function (options, false_by_default) { + if (!(this instanceof Cola.Compressor)) + return new Cola.Compressor(options, false_by_default); + Cola.TreeTransformer.call(this, this.before, this.after); this.options = Cola.defaults(options, { sequences : !false_by_default, properties : !false_by_default, @@ -81,8 +82,8 @@ function Compressor(options, false_by_default) { }, true); }; -Compressor.prototype = new TreeTransformer; -Cola.merge(Compressor.prototype, { +Cola.Compressor.prototype = new Cola.TreeTransformer; +Cola.merge(Cola.Compressor.prototype, { option: function(key) { return this.options[key] }, warn: function() { if (this.options.warnings) @@ -139,7 +140,7 @@ Cola.merge(Compressor.prototype, { function make_node_from_constant(compressor, val, orig) { // XXX: WIP. - // if (val instanceof Cola.AST_Node) return val.transform(new TreeTransformer(null, function(node){ + // if (val instanceof Cola.AST_Node) return val.transform(new Cola.TreeTransformer(null, function(node){ // if (node instanceof Cola.AST_SymbolRef) { // var scope = compressor.find_parent(Cola.AST_Scope); // var def = scope.find_variable(node); @@ -555,7 +556,7 @@ Cola.merge(Compressor.prototype, { statements.forEach(function(stat){ if (stat instanceof Cola.AST_SimpleStatement) { stat.body = (function transform(thing) { - return thing.transform(new TreeTransformer(function(node){ + return thing.transform(new Cola.TreeTransformer(function(node){ if (node instanceof Cola.AST_Call && node.expression instanceof Cola.AST_Function) { return make_node(Cola.AST_UnaryPrefix, node, { operator: "!", @@ -1044,7 +1045,7 @@ Cola.merge(Compressor.prototype, { }); } // pass 3: we should drop declarations not in_use - var tt = new TreeTransformer( + var tt = new Cola.TreeTransformer( function before(node, descend, in_list) { if (node instanceof Cola.AST_Lambda && !(node instanceof Cola.AST_Accessor)) { if (!compressor.option("keep_fargs")) { @@ -1183,7 +1184,7 @@ Cola.merge(Compressor.prototype, { } })); hoist_vars = hoist_vars && var_decl > 1; - var tt = new TreeTransformer( + var tt = new Cola.TreeTransformer( function before(node) { if (node !== self) { if (node instanceof Cola.AST_Directive) { @@ -1555,7 +1556,7 @@ Cola.merge(Compressor.prototype, { var started = false; var stopped = false; var ruined = false; - var tt = new TreeTransformer(function(node, descend, in_list){ + var tt = new Cola.TreeTransformer(function(node, descend, in_list){ if (node instanceof Cola.AST_Lambda || node instanceof Cola.AST_SimpleStatement) { // no need to descend these node types return node; @@ -1724,7 +1725,7 @@ Cola.merge(Compressor.prototype, { }).join(",") + "){" + self.args[self.args.length - 1].value + "})()"; var ast = Cola.parse(code); ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") }); - var comp = new Compressor(compressor.options); + var comp = new Cola.Compressor(compressor.options); ast = ast.transform(comp); ast.figure_out_scope({ screw_ie8: compressor.option("screw_ie8") }); ast.mangle_names(); @@ -1744,7 +1745,7 @@ Cola.merge(Compressor.prototype, { value: arg.print_to_string() }); }); - var code = OutputStream(); + var code = new Cola.OutputStream(); Cola.AST_BlockStatement.prototype._codegen.call(fun, fun, code); code = code.toString().replace(/^\{|\}$/g, ""); args.push(make_node(Cola.AST_String, self.args[self.args.length - 1], { diff --git a/lib/index.html b/lib/index.html index 896a4b8e..4dd04b01 100644 --- a/lib/index.html +++ b/lib/index.html @@ -63,13 +63,13 @@ localStorage.source = source; localStorage.isjs = isjs.checked ? "t" : "f"; - stream = OutputStream({ beautify : true, is_js : isjs.checked }); - compressor = Compressor({ is_js : isjs.checked }); + stream = new Cola.OutputStream({ beautify : true, is_js : isjs.checked }); + compressor = Cola.Compressor({ is_js : isjs.checked }); try { // 1. compile ast = Cola.parse(source, null, isjs.checked); - if(!isjs.checked) ast = translate(ast); + if(!isjs.checked) ast = ast.toJavaScript(); ast.print(stream); translationArea.value = stream.toString(); @@ -82,7 +82,7 @@ ast.compute_char_frequency(); ast.mangle_names({ is_js : isjs.checked, sort : true, toplevel : true }); - stream = OutputStream(); + stream = new Cola.OutputStream(); ast.print(stream); resultArea.value = stream.toString(); } catch(e){ @@ -98,7 +98,7 @@ } function Translate(){ - stream = OutputStream({ beautify : true }); + stream = new Cola.OutputStream({ beautify : true }); translate(Cola.parse(source, null, isjs.checked)).print(stream); return stream.toString(); } diff --git a/lib/output.js b/lib/output.js index 7e2213b9..a1d5687d 100644 --- a/lib/output.js +++ b/lib/output.js @@ -42,10 +42,11 @@ ***********************************************************************/ "use strict"; +!window.Cola && (window.Cola = {}); -function OutputStream(options) { +Cola.OutputStream = function (options) { - options = Cola.defaults(options, { + this.options = Cola.defaults(options, { indent_start : 0, indent_level : 4, quote_keys : false, @@ -66,283 +67,259 @@ function OutputStream(options) { is_js : false }, true); - var indentation = 0; - var current_col = 0; - var current_line = 1; - var current_pos = 0; - var OUTPUT = ""; + this.indentation = 0; + this.current_col = 0; + this.current_line = 1; + this.current_pos = 0; + this.OUTPUT = ""; - function to_ascii(str, identifier) { - return str.replace(/[\u0080-\uffff]/g, function(ch) { - var code = ch.charCodeAt(0).toString(16); - if (code.length <= 2 && !identifier) { - while (code.length < 2) code = "0" + code; - return "\\x" + code; - } else { - while (code.length < 4) code = "0" + code; - return "\\u" + code; - } - }); - }; + this.might_need_space = false; + this.might_need_semicolon = false; + this.last = null; - function make_string(str) { - var dq = 0, sq = 0; - str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0]/g, function(s){ - switch (s) { - case "\\": return "\\\\"; - case "\b": return "\\b"; - case "\f": return "\\f"; - case "\n": return "\\n"; - case "\r": return "\\r"; - case "\u2028": return "\\u2028"; - case "\u2029": return "\\u2029"; - case '"': ++dq; return '"'; - case "'": ++sq; return "'"; - case "\0": return "\\x00"; - } - return s; - }); - if (options.ascii_only) str = to_ascii(str); - if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'"; - else return '"' + str.replace(/\x22/g, '\\"') + '"'; - }; + this.requireSemicolonChars = Cola.makePredicate("( [ + * / - , ."); - function encode_string(str) { - var ret = make_string(str); - if (options.inline_script) - ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); - return ret; - }; - - function make_name(name) { - name = name.toString(); - if (options.ascii_only) - name = to_ascii(name, true); - return name; - }; - - function make_indent(back) { - return Cola.repeat_string(" ", options.indent_start + indentation - back * options.indent_level); - }; - - /* -----[ beautification/minification ]----- */ - - var might_need_space = false; - var might_need_semicolon = false; - var last = null; - - function last_char() { - return last.charAt(last.length - 1); - }; - - function maybe_newline() { - if (options.max_line_len && current_col > options.max_line_len) - print("\n"); - }; - - var requireSemicolonChars = Cola.makePredicate("( [ + * / - , ."); - - function print(str) { - str = String(str); - var ch = str.charAt(0); - if (might_need_semicolon) { - if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(last)) { - if (options.semicolons || requireSemicolonChars(ch)) { - OUTPUT += ";"; - current_col++; - current_pos++; - } else { - OUTPUT += "\n"; - current_pos++; - current_line++; - current_col = 0; - } - if (!options.beautify) - might_need_space = false; - } - might_need_semicolon = false; - maybe_newline(); - } - - if (!options.beautify && options.preserve_line && stack[stack.length - 1]) { - var target_line = stack[stack.length - 1].start.line; - while (current_line < target_line) { - OUTPUT += "\n"; - current_pos++; - current_line++; - current_col = 0; - might_need_space = false; - } - } - - if (might_need_space) { - var prev = last_char(); - if ((Cola.is_identifier_char(prev) - && (Cola.is_identifier_char(ch) || ch == "\\")) - || (/^[\+\-\/]$/.test(ch) && ch == prev)) - { - OUTPUT += " "; - current_col++; - current_pos++; - } - might_need_space = false; - } - var a = str.split(/\r?\n/), n = a.length - 1; - current_line += n; - if (n == 0) { - current_col += a[n].length; - } else { - current_col = a[n].length; - } - current_pos += str.length; - last = str; - OUTPUT += str; - }; - - var space = options.beautify ? function() { - print(" "); - } : function() { - might_need_space = true; - }; - - var indent = options.beautify ? function(half) { - if (options.beautify) { - print(make_indent(half ? 0.5 : 0)); - } - } : Cola.noop; - - var with_indent = options.beautify ? function(col, cont) { - if (col === true) col = next_indent(); - var save_indentation = indentation; - indentation = col; - var ret = cont(); - indentation = save_indentation; - return ret; - } : function(col, cont) { return cont() }; - - var newline = options.beautify ? function() { - print("\n"); - } : Cola.noop; - - var semicolon = options.beautify ? function() { - print(";"); - } : function() { - might_need_semicolon = true; - }; - - function force_semicolon() { - might_need_semicolon = false; - print(";"); - }; - - function next_indent() { - return indentation + options.indent_level; - }; - - function with_block(cont) { - var ret; - print("{"); - newline(); - with_indent(next_indent(), function(){ - ret = cont(); - }); - indent(); - print("}"); - return ret; - }; - - function with_parens(cont) { - print("("); - //XXX: still nice to have that for argument lists - //var ret = with_indent(current_col, cont); - var ret = cont(); - print(")"); - return ret; - }; - - function with_square(cont) { - print("["); - //var ret = with_indent(current_col, cont); - var ret = cont(); - print("]"); - return ret; - }; - - function comma() { - print(","); - space(); - }; - - function colon() { - print(":"); - if (options.space_colon) space(); - }; - - var add_mapping = options.source_map ? function(token, name) { - try { - if (token) options.source_map.add( - token.file || "?", - current_line, current_col, - token.line, token.col, - (!name && token.type == "name") ? token.value : name - ); - } catch(ex) { - Cola.AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", { - file: token.file, - line: token.line, - col: token.col, - cline: current_line, - ccol: current_col, - name: name || "" - }) - } - } : Cola.noop; - - function get() { - return OUTPUT; - }; - - if (options.preamble) { - print(options.preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); + if (this.options.preamble) { + this.print(this.options.preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); } - var stack = []; - return { - get : get, - toString : get, - indent : indent, - indentation : function() { return indentation }, - current_width : function() { return current_col - indentation }, - should_break : function() { return options.width && this.current_width() >= options.width }, - newline : newline, - print : print, - space : space, - comma : comma, - colon : colon, - last : function() { return last }, - semicolon : semicolon, - force_semicolon : force_semicolon, - to_ascii : to_ascii, - print_name : function(name) { print(make_name(name)) }, - print_string : function(str) { print(encode_string(str)) }, - next_indent : next_indent, - with_indent : with_indent, - with_block : with_block, - with_parens : with_parens, - with_square : with_square, - add_mapping : add_mapping, - option : function(opt) { return options[opt] }, - line : function() { return current_line }, - col : function() { return current_col }, - pos : function() { return current_pos }, - push_node : function(node) { stack.push(node) }, - pop_node : function() { return stack.pop() }, - stack : function() { return stack }, - parent : function(n) { - return stack[stack.length - 2 - (n || 0)]; - } - }; + this.stack = []; +}; +Cola.OutputStream.prototype.to_ascii = function (str, identifier) { + return str.replace(/[\u0080-\uffff]/g, function(ch) { + var code = ch.charCodeAt(0).toString(16); + if (code.length <= 2 && !identifier) { + while (code.length < 2) code = "0" + code; + return "\\x" + code; + } else { + while (code.length < 4) code = "0" + code; + return "\\u" + code; + } + }); +}; + +Cola.OutputStream.prototype.make_string = function (str) { + var dq = 0, sq = 0; + str = str.replace(/[\\\b\f\n\r\t\x22\x27\u2028\u2029\0]/g, function(s){ + switch (s) { + case "\\": return "\\\\"; + case "\b": return "\\b"; + case "\f": return "\\f"; + case "\n": return "\\n"; + case "\r": return "\\r"; + case "\u2028": return "\\u2028"; + case "\u2029": return "\\u2029"; + case '"': ++dq; return '"'; + case "'": ++sq; return "'"; + case "\0": return "\\x00"; + } + return s; + }); + if (this.options.ascii_only) str = this.to_ascii(str); + if (dq > sq) return "'" + str.replace(/\x27/g, "\\'") + "'"; + else return '"' + str.replace(/\x22/g, '\\"') + '"'; +}; + +Cola.OutputStream.prototype.encode_string = function (str) { + var ret = this.make_string(str); + if (this.options.inline_script) + ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); + return ret; +}; + +Cola.OutputStream.prototype.make_name = function (name) { + name = name.toString(); + if (this.options.ascii_only) + name = this.to_ascii(name, true); + return name; +}; + +Cola.OutputStream.prototype.make_indent = function (back) { + return Cola.repeat_string(" ", this.options.indent_start + this.indentation - back * this.options.indent_level); +}; + +/* -----[ beautification/minification ]----- */ + +Cola.OutputStream.prototype.last_char = function () { + return this.last.charAt(this.last.length - 1); +}; + +Cola.OutputStream.prototype.maybe_newline = function () { + if (this.options.max_line_len && this.current_col > this.options.max_line_len) + this.print("\n"); +}; + +Cola.OutputStream.prototype.print = function (str) { + str = String(str); + var ch = str.charAt(0); + if (this.might_need_semicolon) { + if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(this.last)) { + if (this.options.semicolons || this.requireSemicolonChars(ch)) { + this.OUTPUT += ";"; + this.current_col++; + this.current_pos++; + } else { + this.OUTPUT += "\n"; + this.current_pos++; + this.current_line++; + this.current_col = 0; + } + if (!this.options.beautify) + this.might_need_space = false; + } + this.might_need_semicolon = false; + this.maybe_newline(); + } + + if (!this.options.beautify && this.options.preserve_line && this.stack[stack.length - 1]) { + var target_line = this.stack[stack.length - 1].start.line; + while (this.current_line < target_line) { + this.OUTPUT += "\n"; + this.current_pos++; + this.current_line++; + this.current_col = 0; + this.might_need_space = false; + } + } + + if (this.might_need_space) { + var prev = this.last_char(); + if ((Cola.is_identifier_char(prev) + && (Cola.is_identifier_char(ch) || ch == "\\")) + || (/^[\+\-\/]$/.test(ch) && ch == prev)) + { + this.OUTPUT += " "; + this.current_col++; + this.current_pos++; + } + this.might_need_space = false; + } + var a = str.split(/\r?\n/), n = a.length - 1; + this.current_line += n; + if (n == 0) { + this.current_col += a[n].length; + } else { + this.current_col = a[n].length; + } + this.current_pos += str.length; + this.last = str; + this.OUTPUT += str; +}; + +Cola.OutputStream.prototype.space = function () { + this.options.beautify ? this.print(" ") : this.might_need_space = true; +} + +Cola.OutputStream.prototype.indent = function (half) { + if (this.options.beautify) { + this.print(this.make_indent(half ? 0.5 : 0)); + } +} + +Cola.OutputStream.prototype.with_indent = function (col, cont) { + if(!this.options.beautify) return cont(); + + if (col === true) col = this.next_indent(); + var save_indentation = this.indentation; + this.indentation = col; + var ret = cont(); + this.indentation = save_indentation; + return ret; +} + +Cola.OutputStream.prototype.newline = function () { + if (this.options.beautify) this.print("\n"); +} + +Cola.OutputStream.prototype.semicolon = function () { + this.options.beautify ? this.print(";") : this.might_need_semicolon = true; +} + +Cola.OutputStream.prototype.force_semicolon = function () { + this.might_need_semicolon = false; + this.print(";"); +}; + +Cola.OutputStream.prototype.next_indent = function () { + return this.indentation + this.options.indent_level; +}; + +Cola.OutputStream.prototype.with_block = function (cont) { + var ret; + this.print("{"); + this.newline(); + this.with_indent(this.next_indent(), function(){ + ret = cont(); + }); + this.indent(); + this.print("}"); + return ret; +}; + +Cola.OutputStream.prototype.with_parens = function (cont) { + this.print("("); + //XXX: still nice to have that for argument lists + //var ret = this.with_indent(this.current_col, cont); + var ret = cont(); + this.print(")"); + return ret; +}; + +Cola.OutputStream.prototype.with_square = function (cont) { + this.print("["); + //var ret = this.with_indent(this.current_col, cont); + var ret = cont(); + this.print("]"); + return ret; +}; + +Cola.OutputStream.prototype.comma = function () { + this.print(","); + this.space(); +}; + +Cola.OutputStream.prototype.colon = function () { + this.print(":"); + if (this.options.space_colon) this.space(); +}; + +Cola.OutputStream.prototype.add_mapping = function (token, name) { + if(!this.options.source_map) return; + + try { + if (token) this.options.source_map.add( + token.file || "?", + this.current_line, this.current_col, + token.line, token.col, + (!name && token.type == "name") ? token.value : name + ); + } catch(ex) { + Cola.AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", { + file: token.file, + line: token.line, + col: token.col, + cline: this.current_line, + ccol: this.current_col, + name: name || "" + }) + } +} + +Cola.OutputStream.prototype.get = function () { + return this.OUTPUT; +}; + +Cola.OutputStream.prototype.toString = function() { return this.OUTPUT }; +Cola.OutputStream.prototype.current_width = function() { return this.current_col - this.indentation }; +Cola.OutputStream.prototype.should_break = function() { return this.options.width && this.current_width() >= this.options.width }; +Cola.OutputStream.prototype.print_name = function(name) { this.print(this.make_name(name)) }; +Cola.OutputStream.prototype.print_string = function(str) { this.print(this.encode_string(str)) }; +Cola.OutputStream.prototype.option = function(opt) { return this.options[opt] }; +Cola.OutputStream.prototype.push_node = function(node) { this.stack.push(node) }; +Cola.OutputStream.prototype.pop_node = function() { return this.stack.pop() }; +Cola.OutputStream.prototype.parent = function(n) { + return this.stack[this.stack.length - 2 - (n || 0)]; }; /* -----[ code generators ]----- */ @@ -372,7 +349,7 @@ function OutputStream(options) { }); Cola.AST_Node.DEFMETHOD("print_to_string", function(options){ - var s = OutputStream(options); + var s = new Cola.OutputStream(options); this.print(s); return s.get(); }); diff --git a/lib/scope.js b/lib/scope.js index cce35134..d2fd1b2e 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -42,8 +42,9 @@ ***********************************************************************/ "use strict"; +!window.Cola && (window.Cola = {}); -function SymbolDef(scope, index, orig) { +Cola.SymbolDef = function (scope, index, orig) { this.name = orig.name; this.orig = [ orig ]; this.scope = scope; @@ -55,7 +56,7 @@ function SymbolDef(scope, index, orig) { this.index = index; }; -SymbolDef.prototype = { +Cola.SymbolDef.prototype = { unmangleable: function(options) { return (this.global && !(options && options.toplevel)) || this.undeclared @@ -157,7 +158,7 @@ Cola.AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ if (globals.has(name)) { g = globals.get(name); } else { - g = new SymbolDef(self, globals.size(), node); + g = new Cola.SymbolDef(self, globals.size(), node); g.undeclared = true; g.global = true; globals.set(name, g); @@ -231,7 +232,7 @@ Cola.AST_Scope.DEFMETHOD("def_function", function(symbol){ Cola.AST_Scope.DEFMETHOD("def_variable", function(symbol){ var def; if (!this.variables.has(symbol.name)) { - def = new SymbolDef(this, this.variables.size(), symbol); + def = new Cola.SymbolDef(this, this.variables.size(), symbol); this.variables.set(symbol.name, def); def.global = !this.parent_scope; } else { @@ -244,7 +245,7 @@ Cola.AST_Scope.DEFMETHOD("def_variable", function(symbol){ Cola.AST_Scope.DEFMETHOD("next_mangled", function(options){ var ext = this.enclosed; out: while (true) { - var m = base54(++this.cname); + var m = Cola.base54(++this.cname); if (!Cola.is_identifier(m, options.is_js)) continue; // skip over "do" // https://github.com/mishoo/UglifyJS2/issues/242 -- do not @@ -362,7 +363,7 @@ Cola.AST_Toplevel.DEFMETHOD("mangle_names", function(options){ } if (node instanceof Cola.AST_Label) { var name; - do name = base54(++lname); while (!Cola.is_identifier(name, options.is_js)); + do name = Cola.base54(++lname); while (!Cola.is_identifier(name, options.is_js)); node.mangled_name = name; return true; } @@ -379,73 +380,73 @@ Cola.AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){ options = this._default_mangler_options(options); var tw = new Cola.TreeWalker(function(node){ if (node instanceof Cola.AST_Constant) - base54.consider(node.print_to_string()); + Cola.base54.consider(node.print_to_string()); else if (node instanceof Cola.AST_Return) - base54.consider("return"); + Cola.base54.consider("return"); else if (node instanceof Cola.AST_Throw) - base54.consider("throw"); + Cola.base54.consider("throw"); else if (node instanceof Cola.AST_Continue) - base54.consider("continue"); + Cola.base54.consider("continue"); else if (node instanceof Cola.AST_Break) - base54.consider("break"); + Cola.base54.consider("break"); else if (node instanceof Cola.AST_Debugger) - base54.consider("debugger"); + Cola.base54.consider("debugger"); else if (node instanceof Cola.AST_Directive) - base54.consider(node.value); + Cola.base54.consider(node.value); else if (node instanceof Cola.AST_While) - base54.consider("while"); + Cola.base54.consider("while"); else if (node instanceof Cola.AST_Do) - base54.consider("do while"); + Cola.base54.consider("do while"); else if (node instanceof Cola.AST_If) { - base54.consider("if"); - if (node.alternative) base54.consider("else"); + Cola.base54.consider("if"); + if (node.alternative) Cola.base54.consider("else"); } else if (node instanceof Cola.AST_Var) - base54.consider("var"); + Cola.base54.consider("var"); else if (node instanceof Cola.AST_Const) - base54.consider("const"); + Cola.base54.consider("const"); else if (node instanceof Cola.AST_Lambda) - base54.consider("function"); + Cola.base54.consider("function"); else if (node instanceof Cola.AST_For) - base54.consider("for"); + Cola.base54.consider("for"); else if (node instanceof Cola.AST_ForIn) - base54.consider("for in"); + Cola.base54.consider("for in"); else if (node instanceof Cola.AST_Switch) - base54.consider("switch"); + Cola.base54.consider("switch"); else if (node instanceof Cola.AST_Case) - base54.consider("case"); + Cola.base54.consider("case"); else if (node instanceof Cola.AST_Default) - base54.consider("default"); + Cola.base54.consider("default"); else if (node instanceof Cola.AST_With) - base54.consider("with"); + Cola.base54.consider("with"); else if (node instanceof Cola.AST_ObjectSetter) - base54.consider("set" + node.key); + Cola.base54.consider("set" + node.key); else if (node instanceof Cola.AST_ObjectGetter) - base54.consider("get" + node.key); + Cola.base54.consider("get" + node.key); else if (node instanceof Cola.AST_ObjectKeyVal) - base54.consider(node.key); + Cola.base54.consider(node.key); else if (node instanceof Cola.AST_New) - base54.consider("new"); + Cola.base54.consider("new"); else if (node instanceof Cola.AST_This) - base54.consider("this"); + Cola.base54.consider("this"); else if (node instanceof Cola.AST_Try) - base54.consider("try"); + Cola.base54.consider("try"); else if (node instanceof Cola.AST_Catch) - base54.consider("catch"); + Cola.base54.consider("catch"); else if (node instanceof Cola.AST_Finally) - base54.consider("finally"); + Cola.base54.consider("finally"); else if (node instanceof Cola.AST_Symbol && node.unmangleable(options)) - base54.consider(node.name); + Cola.base54.consider(node.name); else if (node instanceof Cola.AST_Unary || node instanceof Cola.AST_Binary) - base54.consider(node.operator); + Cola.base54.consider(node.operator); else if (node instanceof Cola.AST_Dot) - base54.consider(node.property); + Cola.base54.consider(node.property); }); this.walk(tw); - base54.sort(); + Cola.base54.sort(); }); -var base54 = (function() { +Cola.base54 = (function() { var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789"; var chars, frequency; function reset() { diff --git a/lib/sourcemap.js b/lib/sourcemap.js index f4deb21b..4a83bc6e 100644 --- a/lib/sourcemap.js +++ b/lib/sourcemap.js @@ -42,10 +42,11 @@ ***********************************************************************/ "use strict"; +!window.Cola && (window.Cola = {}); // a small wrapper around fitzgen's source-map library -function SourceMap(options) { - options = Cola.defaults(options, { +Cola.SourceMap = function (options) { + this.options = Cola.defaults(options, { file : null, root : null, orig : null, @@ -53,35 +54,34 @@ function SourceMap(options) { orig_line_diff : 0, dest_line_diff : 0, }); - var generator = new MOZ_SourceMap.SourceMapGenerator({ - file : options.file, - sourceRoot : options.root + this.generator = new MOZ_SourceMap.SourceMapGenerator({ + file : this.options.file, + sourceRoot : this.options.root }); - var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig); - function add(source, gen_line, gen_col, orig_line, orig_col, name) { - if (orig_map) { - var info = orig_map.originalPositionFor({ - line: orig_line, - column: orig_col - }); - if (info.source === null) { - return; - } - source = info.source; - orig_line = info.line; - orig_col = info.column; - name = info.name; - } - generator.addMapping({ - generated : { line: gen_line + options.dest_line_diff, column: gen_col }, - original : { line: orig_line + options.orig_line_diff, column: orig_col }, - source : source, - name : name + this.orig_map = this.options.orig && new MOZ_SourceMap.SourceMapConsumer(this.options.orig); +} + +Cola.SourceMap.prototype.add = function (source, gen_line, gen_col, orig_line, orig_col, name) { + if (this.orig_map) { + var info = this.orig_map.originalPositionFor({ + line: orig_line, + column: orig_col }); - }; - return { - add : add, - get : function() { return generator }, - toString : function() { return generator.toString() } - }; + if (info.source === null) { + return; + } + source = info.source; + orig_line = info.line; + orig_col = info.column; + name = info.name; + } + this.generator.addMapping({ + generated : { line: gen_line + this.options.dest_line_diff, column: gen_col }, + original : { line: orig_line + this.options.orig_line_diff, column: orig_col }, + source : source, + name : name + }); }; + +Cola.SourceMap.prototype.get = function() { return this.generator }; +Cola.SourceMap.prototype.toString = function() { return this.generator.toString() }; diff --git a/lib/transform.js b/lib/transform.js index 886bfd8c..1d7000d4 100644 --- a/lib/transform.js +++ b/lib/transform.js @@ -42,15 +42,16 @@ ***********************************************************************/ "use strict"; +!window.Cola && (window.Cola = {}); // Tree transformer helpers. -function TreeTransformer(before, after) { +Cola.TreeTransformer = function (before, after) { Cola.TreeWalker.call(this); this.before = before; this.after = after; } -TreeTransformer.prototype = new Cola.TreeWalker; +Cola.TreeTransformer.prototype = new Cola.TreeWalker; (function(undefined){ diff --git a/lib/translate.js b/lib/translate.js index ec35b194..d8dd26eb 100644 --- a/lib/translate.js +++ b/lib/translate.js @@ -35,10 +35,13 @@ ***********************************************************************/ "use strict"; +!window.Cola && (window.Cola = {}); -function translate(tree){ +Cola.AST_Toplevel.prototype.toJavaScript = function(){ + if(this.language == 'js') return this; + this.language = 'js'; - var tt = new TreeTransformer(null, function(node){ + var tt = new Cola.TreeTransformer(null, function(node){ var newNode, props; if(node instanceof Cola.AST_Binary && node.operator == '**'){ @@ -174,5 +177,5 @@ function translate(tree){ return node; }); - return tree.transform(tt); -} \ No newline at end of file + return this.transform(tt); +}; \ No newline at end of file