Refactoring over!
This commit is contained in:
parent
d461f9d927
commit
ea892ef28c
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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], {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
525
lib/output.js
525
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();
|
||||
});
|
||||
|
|
|
|||
79
lib/scope.js
79
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() {
|
||||
|
|
|
|||
|
|
@ -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() };
|
||||
|
|
|
|||
|
|
@ -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){
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
return this.transform(tt);
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user