From bbff7403fbf46f9ad92240ac213df8d30ef31b64 Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Thu, 20 Sep 2018 02:56:13 +0200 Subject: update packages --- node_modules/uglify-js/lib/output.js | 818 +++++++++++++++++++---------------- 1 file changed, 443 insertions(+), 375 deletions(-) (limited to 'node_modules/uglify-js/lib/output.js') diff --git a/node_modules/uglify-js/lib/output.js b/node_modules/uglify-js/lib/output.js index 1aa634501..7f7e74df5 100644 --- a/node_modules/uglify-js/lib/output.js +++ b/node_modules/uglify-js/lib/output.js @@ -52,10 +52,11 @@ function is_some_comments(comment) { function OutputStream(options) { + var readonly = !options; options = defaults(options, { ascii_only : false, beautify : false, - bracketize : false, + braces : false, comments : false, ie8 : false, indent_level : 4, @@ -121,17 +122,22 @@ function OutputStream(options) { } }); } : function(str) { - return str.replace(/[\ud800-\udbff](?![\udc00-\udfff])/g, function(ch) { - return "\\u" + ch.charCodeAt(0).toString(16); - }).replace(/(^|[^\ud800-\udbff])([\udc00-\udfff])/g, function(match, prefix, ch) { - return prefix + "\\u" + ch.charCodeAt(0).toString(16); - }); + var s = ""; + for (var i = 0, len = str.length; i < len; i++) { + if (is_surrogate_pair_head(str[i]) && !is_surrogate_pair_tail(str[i + 1]) + || is_surrogate_pair_tail(str[i]) && !is_surrogate_pair_head(str[i - 1])) { + s += "\\u" + str.charCodeAt(i).toString(16); + } else { + s += str[i]; + } + } + return s; }; function make_string(str, quote) { var dq = 0, sq = 0; str = str.replace(/[\\\b\f\n\r\v\t\x22\x27\u2028\u2029\0\ufeff]/g, - function(s, i){ + function(s, i) { switch (s) { case '"': ++dq; return '"'; case "'": ++sq; return "'"; @@ -167,37 +173,49 @@ function OutputStream(options) { default: return dq > sq ? quote_single() : quote_double(); } - }; + } function encode_string(str, quote) { var ret = make_string(str, quote); if (options.inline_script) { - ret = ret.replace(/<\x2fscript([>\/\t\n\f\r ])/gi, "<\\/script$1"); + ret = ret.replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2"); ret = ret.replace(/\x3c!--/g, "\\x3c!--"); ret = ret.replace(/--\x3e/g, "--\\x3e"); } return ret; - }; + } function make_name(name) { name = name.toString(); name = to_utf8(name, true); return name; - }; + } function make_indent(back) { return repeat_string(" ", options.indent_start + indentation - back * options.indent_level); - }; + } /* -----[ beautification/minification ]----- */ + var has_parens = false; + var line_end = 0; + var line_fixed = true; var might_need_space = false; var might_need_semicolon = false; - var might_add_newline = 0; + var need_newline_indented = false; + var need_space = false; + var newline_insert = -1; var last = ""; var mapping_token, mapping_name, mappings = options.source_map && []; - var do_add_mapping = mappings ? function() { + var adjust_mappings = mappings ? function(line, col) { + mappings.forEach(function(mapping) { + mapping.line += line; + mapping.col += col; + }); + } : noop; + + var flush_mappings = mappings ? function() { mappings.forEach(function(mapping) { try { options.source_map.add( @@ -220,31 +238,30 @@ function OutputStream(options) { mappings = []; } : noop; - var ensure_line_len = options.max_line_len ? function() { - if (current_col > options.max_line_len) { - if (might_add_newline) { - var left = OUTPUT.slice(0, might_add_newline); - var right = OUTPUT.slice(might_add_newline); - if (mappings) { - var delta = right.length - current_col; - mappings.forEach(function(mapping) { - mapping.line++; - mapping.col += delta; - }); - } - OUTPUT = left + "\n" + right; - current_line++; - current_pos++; - current_col = right.length; - } + function insert_newlines(count) { + var index = OUTPUT.lastIndexOf("\n"); + if (line_end < index) line_end = index; + var left = OUTPUT.slice(0, line_end); + var right = OUTPUT.slice(line_end); + adjust_mappings(count, right.length - current_col); + current_line += count; + current_pos += count; + current_col = right.length; + OUTPUT = left; + while (count--) OUTPUT += "\n"; + OUTPUT += right; + } + + var fix_line = options.max_line_len ? function() { + if (line_fixed) { if (current_col > options.max_line_len) { AST_Node.warn("Output exceeds {max_line_len} characters", options); } + return; } - if (might_add_newline) { - might_add_newline = 0; - do_add_mapping(); - } + if (current_col > options.max_line_len) insert_newlines(1); + line_fixed = true; + flush_mappings(); } : noop; var requireSemicolonChars = makePredicate("( [ + * / - , ."); @@ -252,17 +269,31 @@ function OutputStream(options) { function print(str) { str = String(str); var ch = str.charAt(0); + if (need_newline_indented && ch) { + need_newline_indented = false; + if (ch != "\n") { + print("\n"); + indent(); + } + } + if (need_space && ch) { + need_space = false; + if (!/[\s;})]/.test(ch)) { + space(); + } + } + newline_insert = -1; var prev = last.charAt(last.length - 1); if (might_need_semicolon) { might_need_semicolon = false; if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") { - if (options.semicolons || requireSemicolonChars(ch)) { + if (options.semicolons || requireSemicolonChars[ch]) { OUTPUT += ";"; current_col++; current_pos++; } else { - ensure_line_len(); + fix_line(); OUTPUT += "\n"; current_pos++; current_line++; @@ -280,18 +311,6 @@ function OutputStream(options) { } } - if (!options.beautify && options.preserve_line && stack[stack.length - 1]) { - var target_line = stack[stack.length - 1].start.line; - while (current_line < target_line) { - ensure_line_len(); - OUTPUT += "\n"; - current_pos++; - current_line++; - current_col = 0; - might_need_space = false; - } - } - if (might_need_space) { if ((is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")) @@ -313,20 +332,21 @@ function OutputStream(options) { col: current_col }); mapping_token = false; - if (!might_add_newline) do_add_mapping(); + if (line_fixed) flush_mappings(); } OUTPUT += str; + has_parens = str[str.length - 1] == "("; current_pos += str.length; var a = str.split(/\r?\n/), n = a.length - 1; current_line += n; current_col += a[0].length; if (n > 0) { - ensure_line_len(); + fix_line(); current_col = a[n].length; } last = str; - }; + } var space = options.beautify ? function() { print(" "); @@ -349,13 +369,22 @@ function OutputStream(options) { return ret; } : function(col, cont) { return cont() }; - var newline = options.beautify ? function() { - print("\n"); - } : options.max_line_len ? function() { - ensure_line_len(); - might_add_newline = OUTPUT.length; + var may_add_newline = options.max_line_len || options.preserve_line ? function() { + fix_line(); + line_end = OUTPUT.length; + line_fixed = false; } : noop; + var newline = options.beautify ? function() { + if (newline_insert < 0) return print("\n"); + if (OUTPUT[newline_insert] != "\n") { + OUTPUT = OUTPUT.slice(0, newline_insert) + "\n" + OUTPUT.slice(newline_insert); + current_pos++; + current_line++; + } + newline_insert++; + } : may_add_newline; + var semicolon = options.beautify ? function() { print(";"); } : function() { @@ -365,50 +394,56 @@ function OutputStream(options) { 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(){ + with_indent(next_indent(), function() { ret = cont(); }); indent(); print("}"); return ret; - }; + } function with_parens(cont) { print("("); + may_add_newline(); //XXX: still nice to have that for argument lists //var ret = with_indent(current_col, cont); var ret = cont(); + may_add_newline(); print(")"); return ret; - }; + } function with_square(cont) { print("["); + may_add_newline(); //var ret = with_indent(current_col, cont); var ret = cont(); + may_add_newline(); print("]"); return ret; - }; + } function comma() { + may_add_newline(); print(","); + may_add_newline(); space(); - }; + } function colon() { print(":"); space(); - }; + } var add_mapping = mappings ? function(token, name) { mapping_token = token; @@ -416,11 +451,126 @@ function OutputStream(options) { } : noop; function get() { - if (might_add_newline) { - ensure_line_len(); - } + if (!line_fixed) fix_line(); return OUTPUT; - }; + } + + function has_nlb() { + var index = OUTPUT.lastIndexOf("\n"); + return /^ *$/.test(OUTPUT.slice(index + 1)); + } + + function prepend_comments(node) { + var self = this; + var start = node.start; + if (!start) return; + if (start.comments_before && start.comments_before._dumped === self) return; + var comments = start.comments_before; + if (!comments) { + comments = start.comments_before = []; + } + comments._dumped = self; + + if (node instanceof AST_Exit && node.value) { + var tw = new TreeWalker(function(node) { + var parent = tw.parent(); + if (parent instanceof AST_Exit + || parent instanceof AST_Binary && parent.left === node + || parent.TYPE == "Call" && parent.expression === node + || parent instanceof AST_Conditional && parent.condition === node + || parent instanceof AST_Dot && parent.expression === node + || parent instanceof AST_Sequence && parent.expressions[0] === node + || parent instanceof AST_Sub && parent.expression === node + || parent instanceof AST_UnaryPostfix) { + var text = node.start.comments_before; + if (text && text._dumped !== self) { + text._dumped = self; + comments = comments.concat(text); + } + } else { + return true; + } + }); + tw.push(node); + node.value.walk(tw); + } + + if (current_pos == 0) { + if (comments.length > 0 && options.shebang && comments[0].type == "comment5") { + print("#!" + comments.shift().value + "\n"); + indent(); + } + var preamble = options.preamble; + if (preamble) { + print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); + } + } + + comments = comments.filter(comment_filter, node); + if (comments.length == 0) return; + var last_nlb = has_nlb(); + comments.forEach(function(c, i) { + if (!last_nlb) { + if (c.nlb) { + print("\n"); + indent(); + last_nlb = true; + } else if (i > 0) { + space(); + } + } + if (/comment[134]/.test(c.type)) { + print("//" + c.value.replace(/[@#]__PURE__/g, ' ') + "\n"); + indent(); + last_nlb = true; + } else if (c.type == "comment2") { + print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/"); + last_nlb = false; + } + }); + if (!last_nlb) { + if (start.nlb) { + print("\n"); + indent(); + } else { + space(); + } + } + } + + function append_comments(node, tail) { + var self = this; + var token = node.end; + if (!token) return; + var comments = token[tail ? "comments_before" : "comments_after"]; + if (!comments || comments._dumped === self) return; + if (!(node instanceof AST_Statement || all(comments, function(c) { + return !/comment[134]/.test(c.type); + }))) return; + comments._dumped = self; + var insert = OUTPUT.length; + comments.filter(comment_filter, node).forEach(function(c, i) { + need_space = false; + if (need_newline_indented) { + print("\n"); + indent(); + need_newline_indented = false; + } else if (c.nlb && (i > 0 || !has_nlb())) { + print("\n"); + indent(); + } else if (i > 0 || !tail) { + space(); + } + if (/comment[134]/.test(c.type)) { + print("//" + c.value.replace(/[@#]__PURE__/g, ' ')); + need_newline_indented = true; + } else if (c.type == "comment2") { + print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/"); + need_space = true; + } + }); + if (OUTPUT.length > insert) newline_insert = insert; + } var stack = []; return { @@ -430,6 +580,7 @@ function OutputStream(options) { indentation : function() { return indentation }, current_width : function() { return current_col - indentation }, should_break : function() { return options.width && this.current_width() >= options.width }, + has_parens : function() { return has_parens }, newline : newline, print : print, space : space, @@ -459,34 +610,41 @@ function OutputStream(options) { with_square : with_square, add_mapping : add_mapping, option : function(opt) { return options[opt] }, - comment_filter : comment_filter, + prepend_comments: readonly ? noop : prepend_comments, + append_comments : readonly || comment_filter === return_false ? noop : append_comments, 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() }, + pop_node : options.preserve_line ? function() { + var node = stack.pop(); + if (node.start && node.start.line > current_line) { + insert_newlines(node.start.line - current_line); + } + } : function() { + stack.pop(); + }, parent : function(n) { return stack[stack.length - 2 - (n || 0)]; } }; - -}; +} /* -----[ code generators ]----- */ -(function(){ +(function() { /* -----[ utils ]----- */ function DEFPRINT(nodetype, generator) { nodetype.DEFMETHOD("_codegen", generator); - }; + } var in_directive = false; var active_scope = null; var use_asm = null; - AST_Node.DEFMETHOD("print", function(stream, force_parens){ + AST_Node.DEFMETHOD("print", function(stream, force_parens) { var self = this, generator = self._codegen; if (self instanceof AST_Scope) { active_scope = self; @@ -495,9 +653,10 @@ function OutputStream(options) { use_asm = active_scope; } function doit() { - self.add_comments(stream); + stream.prepend_comments(self); self.add_source_map(stream); generator(self, stream); + stream.append_comments(self); } stream.push_node(self); if (force_parens || self.needs_parens(stream)) { @@ -512,130 +671,53 @@ function OutputStream(options) { }); AST_Node.DEFMETHOD("_print", AST_Node.prototype.print); - AST_Node.DEFMETHOD("print_to_string", function(options){ + AST_Node.DEFMETHOD("print_to_string", function(options) { var s = OutputStream(options); - if (!options) s._readonly = true; this.print(s); return s.get(); }); - /* -----[ comments ]----- */ - - AST_Node.DEFMETHOD("add_comments", function(output){ - if (output._readonly) return; - var self = this; - var start = self.start; - if (start && !start._comments_dumped) { - start._comments_dumped = true; - var comments = start.comments_before || []; - - // XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112 - // and https://github.com/mishoo/UglifyJS2/issues/372 - if (self instanceof AST_Exit && self.value) { - self.value.walk(new TreeWalker(function(node){ - if (node.start && node.start.comments_before) { - comments = comments.concat(node.start.comments_before); - node.start.comments_before = []; - } - if (node instanceof AST_Function || - node instanceof AST_Array || - node instanceof AST_Object) - { - return true; // don't go inside. - } - })); - } - - if (output.pos() == 0) { - if (comments.length > 0 && output.option("shebang") && comments[0].type == "comment5") { - output.print("#!" + comments.shift().value + "\n"); - output.indent(); - } - var preamble = output.option("preamble"); - if (preamble) { - output.print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n")); - } - } - - comments = comments.filter(output.comment_filter, self); - - // Keep single line comments after nlb, after nlb - if (!output.option("beautify") && comments.length > 0 && - /comment[134]/.test(comments[0].type) && - output.col() !== 0 && comments[0].nlb) - { - output.print("\n"); - } - - comments.forEach(function(c){ - if (/comment[134]/.test(c.type)) { - output.print("//" + c.value + "\n"); - output.indent(); - } - else if (c.type == "comment2") { - output.print("/*" + c.value + "*/"); - if (start.nlb) { - output.print("\n"); - output.indent(); - } else { - output.space(); - } - } - }); - } - }); - /* -----[ PARENTHESES ]----- */ function PARENS(nodetype, func) { if (Array.isArray(nodetype)) { - nodetype.forEach(function(nodetype){ + nodetype.forEach(function(nodetype) { PARENS(nodetype, func); }); } else { nodetype.DEFMETHOD("needs_parens", func); } - }; + } - PARENS(AST_Node, function(){ - return false; - }); + PARENS(AST_Node, return_false); // a function expression needs parens around it when it's provably // the first token to appear in a statement. - PARENS(AST_Function, function(output){ - if (first_in_statement(output)) { - return true; - } - + PARENS(AST_Function, function(output) { + if (!output.has_parens() && first_in_statement(output)) return true; if (output.option('webkit')) { var p = output.parent(); - if (p instanceof AST_PropAccess && p.expression === this) { - return true; - } + if (p instanceof AST_PropAccess && p.expression === this) return true; } - if (output.option('wrap_iife')) { var p = output.parent(); - return p instanceof AST_Call && p.expression === this; + if (p instanceof AST_Call && p.expression === this) return true; } - - return false; }); // same goes for an object literal, because otherwise it would be // interpreted as a block of code. - PARENS(AST_Object, function(output){ - return first_in_statement(output); + PARENS(AST_Object, function(output) { + return !output.has_parens() && first_in_statement(output); }); - PARENS(AST_Unary, function(output){ + PARENS(AST_Unary, function(output) { var p = output.parent(); return p instanceof AST_PropAccess && p.expression === this || p instanceof AST_Call && p.expression === this; }); - PARENS(AST_Sequence, function(output){ + PARENS(AST_Sequence, function(output) { var p = output.parent(); return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) || p instanceof AST_Unary // !(foo, bar, baz) @@ -649,7 +731,7 @@ function OutputStream(options) { ; }); - PARENS(AST_Binary, function(output){ + PARENS(AST_Binary, function(output) { var p = output.parent(); // (foo && bar)() if (p instanceof AST_Call && p.expression === this) @@ -672,7 +754,7 @@ function OutputStream(options) { } }); - PARENS(AST_PropAccess, function(output){ + PARENS(AST_PropAccess, function(output) { var p = output.parent(); if (p instanceof AST_New && p.expression === this) { // i.e. new (foo.bar().baz) @@ -693,21 +775,21 @@ function OutputStream(options) { } }); - PARENS(AST_Call, function(output){ - var p = output.parent(), p1; - if (p instanceof AST_New && p.expression === this) - return true; - - // workaround for Safari bug. + PARENS(AST_Call, function(output) { + var p = output.parent(); + if (p instanceof AST_New && p.expression === this) return true; // https://bugs.webkit.org/show_bug.cgi?id=123506 - return this.expression instanceof AST_Function - && p instanceof AST_PropAccess - && p.expression === this - && (p1 = output.parent(1)) instanceof AST_Assign - && p1.left === p; + if (output.option('webkit')) { + var g = output.parent(1); + return this.expression instanceof AST_Function + && p instanceof AST_PropAccess + && p.expression === this + && g instanceof AST_Assign + && g.left === p; + } }); - PARENS(AST_New, function(output){ + PARENS(AST_New, function(output) { var p = output.parent(); if (!need_constructor_parens(this, output) && (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]() @@ -715,7 +797,7 @@ function OutputStream(options) { return true; }); - PARENS(AST_Number, function(output){ + PARENS(AST_Number, function(output) { var p = output.parent(); if (p instanceof AST_PropAccess && p.expression === this) { var value = this.getValue(); @@ -725,7 +807,7 @@ function OutputStream(options) { } }); - PARENS([ AST_Assign, AST_Conditional ], function(output){ + PARENS([ AST_Assign, AST_Conditional ], function(output) { var p = output.parent(); // !(a = false) → true if (p instanceof AST_Unary) @@ -746,11 +828,11 @@ function OutputStream(options) { /* -----[ PRINTERS ]----- */ - DEFPRINT(AST_Directive, function(self, output){ + DEFPRINT(AST_Directive, function(self, output) { output.print_string(self.value, self.quote); output.semicolon(); }); - DEFPRINT(AST_Debugger, function(self, output){ + DEFPRINT(AST_Debugger, function(self, output) { output.print("debugger"); output.semicolon(); }); @@ -760,7 +842,7 @@ function OutputStream(options) { function display_body(body, is_toplevel, output, allow_directives) { var last = body.length - 1; in_directive = allow_directives; - body.forEach(function(stmt, i){ + body.forEach(function(stmt, i) { if (in_directive === true && !(stmt instanceof AST_Directive || stmt instanceof AST_EmptyStatement || (stmt instanceof AST_SimpleStatement && stmt.body instanceof AST_String) @@ -783,66 +865,74 @@ function OutputStream(options) { } }); in_directive = false; - }; + } - AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){ + AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output) { force_statement(this.body, output); }); - DEFPRINT(AST_Statement, function(self, output){ + DEFPRINT(AST_Statement, function(self, output) { self.body.print(output); output.semicolon(); }); - DEFPRINT(AST_Toplevel, function(self, output){ + DEFPRINT(AST_Toplevel, function(self, output) { display_body(self.body, true, output, true); output.print(""); }); - DEFPRINT(AST_LabeledStatement, function(self, output){ + DEFPRINT(AST_LabeledStatement, function(self, output) { self.label.print(output); output.colon(); self.body.print(output); }); - DEFPRINT(AST_SimpleStatement, function(self, output){ + DEFPRINT(AST_SimpleStatement, function(self, output) { self.body.print(output); output.semicolon(); }); - function print_bracketed(body, output, allow_directives) { - if (body.length > 0) output.with_block(function(){ - display_body(body, false, output, allow_directives); + function print_braced_empty(self, output) { + output.print("{"); + output.with_indent(output.next_indent(), function() { + output.append_comments(self, true); }); - else output.print("{}"); - }; - DEFPRINT(AST_BlockStatement, function(self, output){ - print_bracketed(self.body, output); + output.print("}"); + } + function print_braced(self, output, allow_directives) { + if (self.body.length > 0) { + output.with_block(function() { + display_body(self.body, false, output, allow_directives); + }); + } else print_braced_empty(self, output); + } + DEFPRINT(AST_BlockStatement, function(self, output) { + print_braced(self, output); }); - DEFPRINT(AST_EmptyStatement, function(self, output){ + DEFPRINT(AST_EmptyStatement, function(self, output) { output.semicolon(); }); - DEFPRINT(AST_Do, function(self, output){ + DEFPRINT(AST_Do, function(self, output) { output.print("do"); output.space(); make_block(self.body, output); output.space(); output.print("while"); output.space(); - output.with_parens(function(){ + output.with_parens(function() { self.condition.print(output); }); output.semicolon(); }); - DEFPRINT(AST_While, function(self, output){ + DEFPRINT(AST_While, function(self, output) { output.print("while"); output.space(); - output.with_parens(function(){ + output.with_parens(function() { self.condition.print(output); }); output.space(); self._do_print_body(output); }); - DEFPRINT(AST_For, function(self, output){ + DEFPRINT(AST_For, function(self, output) { output.print("for"); output.space(); - output.with_parens(function(){ + output.with_parens(function() { if (self.init) { if (self.init instanceof AST_Definitions) { self.init.print(output); @@ -868,10 +958,10 @@ function OutputStream(options) { output.space(); self._do_print_body(output); }); - DEFPRINT(AST_ForIn, function(self, output){ + DEFPRINT(AST_ForIn, function(self, output) { output.print("for"); output.space(); - output.with_parens(function(){ + output.with_parens(function() { self.init.print(output); output.space(); output.print("in"); @@ -881,10 +971,10 @@ function OutputStream(options) { output.space(); self._do_print_body(output); }); - DEFPRINT(AST_With, function(self, output){ + DEFPRINT(AST_With, function(self, output) { output.print("with"); output.space(); - output.with_parens(function(){ + output.with_parens(function() { self.expression.print(output); }); output.space(); @@ -892,7 +982,7 @@ function OutputStream(options) { }); /* -----[ functions ]----- */ - AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){ + AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword) { var self = this; if (!nokeyword) { output.print("function"); @@ -901,55 +991,46 @@ function OutputStream(options) { output.space(); self.name.print(output); } - output.with_parens(function(){ - self.argnames.forEach(function(arg, i){ + output.with_parens(function() { + self.argnames.forEach(function(arg, i) { if (i) output.comma(); arg.print(output); }); }); output.space(); - print_bracketed(self.body, output, true); + print_braced(self, output, true); }); - DEFPRINT(AST_Lambda, function(self, output){ + DEFPRINT(AST_Lambda, function(self, output) { self._do_print(output); }); - /* -----[ exits ]----- */ - AST_Exit.DEFMETHOD("_do_print", function(output, kind){ + /* -----[ jumps ]----- */ + function print_jump(output, kind, target) { output.print(kind); - if (this.value) { + if (target) { output.space(); - this.value.print(output); + target.print(output); } output.semicolon(); - }); - DEFPRINT(AST_Return, function(self, output){ - self._do_print(output, "return"); - }); - DEFPRINT(AST_Throw, function(self, output){ - self._do_print(output, "throw"); - }); + } - /* -----[ loop control ]----- */ - AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){ - output.print(kind); - if (this.label) { - output.space(); - this.label.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){ - self._do_print(output, "break"); + DEFPRINT(AST_Break, function(self, output) { + print_jump(output, "break", self.label); }); - DEFPRINT(AST_Continue, function(self, output){ - self._do_print(output, "continue"); + DEFPRINT(AST_Continue, function(self, output) { + print_jump(output, "continue", self.label); }); /* -----[ if ]----- */ function make_then(self, output) { var b = self.body; - if (output.option("bracketize") + if (output.option("braces") || output.option("ie8") && b instanceof AST_Do) return make_block(b, output); // The squeezer replaces "block"-s that contain only a single @@ -958,7 +1039,7 @@ function OutputStream(options) { // IF having an ELSE clause where the THEN clause ends in an // IF *without* an ELSE block (then the outer ELSE would refer // to the inner IF). This function checks for this case and - // adds the block brackets if needed. + // adds the block braces if needed. if (!b) return output.force_semicolon(); while (true) { if (b instanceof AST_If) { @@ -974,11 +1055,11 @@ function OutputStream(options) { else break; } force_statement(self.body, output); - }; - DEFPRINT(AST_If, function(self, output){ + } + DEFPRINT(AST_If, function(self, output) { output.print("if"); output.space(); - output.with_parens(function(){ + output.with_parens(function() { self.condition.print(output); }); output.space(); @@ -997,17 +1078,17 @@ function OutputStream(options) { }); /* -----[ switch ]----- */ - DEFPRINT(AST_Switch, function(self, output){ + DEFPRINT(AST_Switch, function(self, output) { output.print("switch"); output.space(); - output.with_parens(function(){ + output.with_parens(function() { self.expression.print(output); }); output.space(); var last = self.body.length - 1; - if (last < 0) output.print("{}"); - else output.with_block(function(){ - self.body.forEach(function(branch, i){ + if (last < 0) print_braced_empty(self, output); + else output.with_block(function() { + self.body.forEach(function(branch, i) { output.indent(true); branch.print(output); if (i < last && branch.body.length > 0) @@ -1015,19 +1096,19 @@ function OutputStream(options) { }); }); }); - AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){ + AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output) { output.newline(); - this.body.forEach(function(stmt){ + this.body.forEach(function(stmt) { output.indent(); stmt.print(output); output.newline(); }); }); - DEFPRINT(AST_Default, function(self, output){ + DEFPRINT(AST_Default, function(self, output) { output.print("default:"); self._do_print_body(output); }); - DEFPRINT(AST_Case, function(self, output){ + DEFPRINT(AST_Case, function(self, output) { output.print("case"); output.space(); self.expression.print(output); @@ -1036,10 +1117,10 @@ function OutputStream(options) { }); /* -----[ exceptions ]----- */ - DEFPRINT(AST_Try, function(self, output){ + DEFPRINT(AST_Try, function(self, output) { output.print("try"); output.space(); - print_bracketed(self.body, output); + print_braced(self, output); if (self.bcatch) { output.space(); self.bcatch.print(output); @@ -1049,37 +1130,30 @@ function OutputStream(options) { self.bfinally.print(output); } }); - DEFPRINT(AST_Catch, function(self, output){ + DEFPRINT(AST_Catch, function(self, output) { output.print("catch"); output.space(); - output.with_parens(function(){ + output.with_parens(function() { self.argname.print(output); }); output.space(); - print_bracketed(self.body, output); + print_braced(self, output); }); - DEFPRINT(AST_Finally, function(self, output){ + DEFPRINT(AST_Finally, function(self, output) { output.print("finally"); output.space(); - print_bracketed(self.body, output); + print_braced(self, output); }); - /* -----[ var/const ]----- */ - AST_Definitions.DEFMETHOD("_do_print", function(output, kind){ - output.print(kind); + DEFPRINT(AST_Var, function(self, output) { + output.print("var"); output.space(); - this.definitions.forEach(function(def, i){ + self.definitions.forEach(function(def, i) { if (i) output.comma(); def.print(output); }); var p = output.parent(); - var in_for = p instanceof AST_For || p instanceof AST_ForIn; - var avoid_semicolon = in_for && p.init === this; - if (!avoid_semicolon) - output.semicolon(); - }); - DEFPRINT(AST_Var, function(self, output){ - self._do_print(output, "var"); + if (p && p.init !== self || !(p instanceof AST_For || p instanceof AST_ForIn)) output.semicolon(); }); function parenthesize_for_noin(node, output, noin) { @@ -1094,9 +1168,9 @@ function OutputStream(options) { } })); node.print(output, parens); - }; + } - DEFPRINT(AST_VarDef, function(self, output){ + DEFPRINT(AST_VarDef, function(self, output) { self.name.print(output); if (self.value) { output.space(); @@ -1109,28 +1183,27 @@ function OutputStream(options) { }); /* -----[ other expressions ]----- */ - DEFPRINT(AST_Call, function(self, output){ + DEFPRINT(AST_Call, function(self, output) { self.expression.print(output); if (self instanceof AST_New && !need_constructor_parens(self, output)) return; if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) { output.add_mapping(self.start); } - output.with_parens(function(){ - self.args.forEach(function(expr, i){ + output.with_parens(function() { + self.args.forEach(function(expr, i) { if (i) output.comma(); expr.print(output); }); }); }); - DEFPRINT(AST_New, function(self, output){ + DEFPRINT(AST_New, function(self, output) { output.print("new"); output.space(); AST_Call.prototype._codegen(self, output); }); - - AST_Sequence.DEFMETHOD("_do_print", function(output){ - this.expressions.forEach(function(node, index) { + DEFPRINT(AST_Sequence, function(self, output) { + self.expressions.forEach(function(node, index) { if (index > 0) { output.comma(); if (output.should_break()) { @@ -1141,22 +1214,11 @@ function OutputStream(options) { node.print(output); }); }); - DEFPRINT(AST_Sequence, function(self, output){ - self._do_print(output); - // var p = output.parent(); - // if (p instanceof AST_Statement) { - // output.with_indent(output.next_indent(), function(){ - // self._do_print(output); - // }); - // } else { - // self._do_print(output); - // } - }); - DEFPRINT(AST_Dot, function(self, output){ + DEFPRINT(AST_Dot, function(self, output) { var expr = self.expression; expr.print(output); var prop = self.property; - if (output.option("ie8") && RESERVED_WORDS(prop)) { + if (output.option("ie8") && RESERVED_WORDS[prop]) { output.print("["); output.add_mapping(self.end); output.print_string(prop); @@ -1173,13 +1235,13 @@ function OutputStream(options) { output.print_name(prop); } }); - DEFPRINT(AST_Sub, function(self, output){ + DEFPRINT(AST_Sub, function(self, output) { self.expression.print(output); output.print("["); self.property.print(output); output.print("]"); }); - DEFPRINT(AST_UnaryPrefix, function(self, output){ + DEFPRINT(AST_UnaryPrefix, function(self, output) { var op = self.operator; output.print(op); if (/^[a-z]/i.test(op) @@ -1190,11 +1252,11 @@ function OutputStream(options) { } self.expression.print(output); }); - DEFPRINT(AST_UnaryPostfix, function(self, output){ + DEFPRINT(AST_UnaryPostfix, function(self, output) { self.expression.print(output); output.print(self.operator); }); - DEFPRINT(AST_Binary, function(self, output){ + DEFPRINT(AST_Binary, function(self, output) { var op = self.operator; self.left.print(output); if (op[0] == ">" /* ">>" ">>>" ">" ">=" */ @@ -1220,7 +1282,7 @@ function OutputStream(options) { } self.right.print(output); }); - DEFPRINT(AST_Conditional, function(self, output){ + DEFPRINT(AST_Conditional, function(self, output) { self.condition.print(output); output.space(); output.print("?"); @@ -1232,11 +1294,11 @@ function OutputStream(options) { }); /* -----[ literals ]----- */ - DEFPRINT(AST_Array, function(self, output){ - output.with_square(function(){ + DEFPRINT(AST_Array, function(self, output) { + output.with_square(function() { var a = self.elements, len = a.length; if (len > 0) output.space(); - a.forEach(function(exp, i){ + a.forEach(function(exp, i) { if (i) output.comma(); exp.print(output); // If the final element is a hole, we need to make sure it @@ -1248,9 +1310,9 @@ function OutputStream(options) { if (len > 0) output.space(); }); }); - 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(self, output) { + if (self.properties.length > 0) output.with_block(function() { + self.properties.forEach(function(prop, i) { if (i) { output.print(","); output.newline(); @@ -1260,18 +1322,15 @@ function OutputStream(options) { }); output.newline(); }); - else output.print("{}"); + else print_braced_empty(self, output); }); function print_property_name(key, quote, output) { if (output.option("quote_keys")) { - output.print_string(key + ""); - } else if ((typeof key == "number" - || !output.option("beautify") - && +key + "" == key) - && parseFloat(key) >= 0) { + output.print_string(key); + } else if ("" + +key == key && key >= 0) { output.print(make_num(key)); - } else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) { + } else if (RESERVED_WORDS[key] ? !output.option("ie8") : is_identifier_string(key)) { if (quote && output.option("keep_quoted_props")) { output.print_string(key, quote); } else { @@ -1282,7 +1341,7 @@ function OutputStream(options) { } } - DEFPRINT(AST_ObjectKeyVal, function(self, output){ + DEFPRINT(AST_ObjectKeyVal, function(self, output) { print_property_name(self.key, self.quote, output); output.colon(); self.value.print(output); @@ -1293,27 +1352,27 @@ function OutputStream(options) { print_property_name(this.key.name, this.quote, output); this.value._do_print(output, true); }); - DEFPRINT(AST_ObjectSetter, function(self, output){ + DEFPRINT(AST_ObjectSetter, function(self, output) { self._print_getter_setter("set", output); }); - DEFPRINT(AST_ObjectGetter, function(self, output){ + DEFPRINT(AST_ObjectGetter, function(self, output) { self._print_getter_setter("get", output); }); - DEFPRINT(AST_Symbol, function(self, output){ + DEFPRINT(AST_Symbol, function(self, output) { var def = self.definition(); output.print_name(def ? def.mangled_name || def.name : self.name); }); DEFPRINT(AST_Hole, noop); - DEFPRINT(AST_This, function(self, output){ + DEFPRINT(AST_This, function(self, output) { output.print("this"); }); - DEFPRINT(AST_Constant, function(self, output){ + DEFPRINT(AST_Constant, function(self, output) { output.print(self.getValue()); }); - DEFPRINT(AST_String, function(self, output){ + DEFPRINT(AST_String, function(self, output) { output.print_string(self.getValue(), self.quote, in_directive); }); - DEFPRINT(AST_Number, function(self, output){ + DEFPRINT(AST_Number, function(self, output) { if (use_asm && self.start && self.start.raw != null) { output.print(self.start.raw); } else { @@ -1321,7 +1380,7 @@ function OutputStream(options) { } }); - DEFPRINT(AST_RegExp, function(self, output){ + DEFPRINT(AST_RegExp, function(self, output) { var regexp = self.getValue(); var str = regexp.toString(); if (regexp.raw_source) { @@ -1335,7 +1394,7 @@ function OutputStream(options) { }); function force_statement(stat, output) { - if (output.option("bracketize")) { + if (output.option("braces")) { make_block(stat, output); } else { if (!stat || stat instanceof AST_EmptyStatement) @@ -1343,7 +1402,7 @@ function OutputStream(options) { else stat.print(output); } - }; + } // self should be AST_New. decide if we want to show parens or not. function need_constructor_parens(self, output) { @@ -1351,7 +1410,7 @@ function OutputStream(options) { if (self.args.length > 0) return true; return output.option("beautify"); - }; + } function best_of(a) { var best = a[0], len = best.length; @@ -1362,84 +1421,93 @@ function OutputStream(options) { } } return best; - }; + } function make_num(num) { - var str = num.toString(10), a = [ str.replace(/^0\./, ".").replace('e+', 'e') ], m; + var str = num.toString(10).replace(/^0\./, ".").replace("e+", "e"); + var candidates = [ str ]; if (Math.floor(num) === num) { - if (num >= 0) { - a.push("0x" + num.toString(16).toLowerCase(), // probably pointless - "0" + num.toString(8)); // same. + if (num < 0) { + candidates.push("-0x" + (-num).toString(16).toLowerCase()); } else { - a.push("-0x" + (-num).toString(16).toLowerCase(), // probably pointless - "-0" + (-num).toString(8)); // same. + candidates.push("0x" + num.toString(16).toLowerCase()); } - if ((m = /^(.*?)(0+)$/.exec(num))) { - a.push(m[1] + "e" + m[2].length); - } - } else if ((m = /^0?\.(0+)(.*)$/.exec(num))) { - a.push(m[2] + "e-" + (m[1].length + m[2].length), - str.substr(str.indexOf("."))); } - return best_of(a); - }; + var match, len, digits; + if (match = /^\.0+/.exec(str)) { + len = match[0].length; + digits = str.slice(len); + candidates.push(digits + "e-" + (digits.length + len - 1)); + } else if (match = /0+$/.exec(str)) { + len = match[0].length; + candidates.push(str.slice(0, -len) + "e" + len); + } else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) { + candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length)); + } + return best_of(candidates); + } function make_block(stmt, output) { if (!stmt || stmt instanceof AST_EmptyStatement) output.print("{}"); else if (stmt instanceof AST_BlockStatement) stmt.print(output); - else output.with_block(function(){ + else output.with_block(function() { output.indent(); stmt.print(output); output.newline(); }); - }; + } /* -----[ source map generators ]----- */ function DEFMAP(nodetype, generator) { - nodetype.DEFMETHOD("add_source_map", function(stream){ - generator(this, stream); + nodetype.forEach(function(nodetype) { + nodetype.DEFMETHOD("add_source_map", generator); }); - }; - - // We could easily add info for ALL nodes, but it seems to me that - // would be quite wasteful, hence this noop in the base class. - DEFMAP(AST_Node, noop); + } - function basic_sourcemap_gen(self, output) { - output.add_mapping(self.start); - }; + DEFMAP([ + // We could easily add info for ALL nodes, but it seems to me that + // would be quite wasteful, hence this noop in the base class. + AST_Node, + // since the label symbol will mark it + AST_LabeledStatement, + AST_Toplevel, + ], noop); // XXX: I'm not exactly sure if we need it for all of these nodes, // or if we should add even more. - - DEFMAP(AST_Directive, basic_sourcemap_gen); - DEFMAP(AST_Debugger, basic_sourcemap_gen); - DEFMAP(AST_Symbol, basic_sourcemap_gen); - DEFMAP(AST_Jump, basic_sourcemap_gen); - DEFMAP(AST_StatementWithBody, basic_sourcemap_gen); - DEFMAP(AST_LabeledStatement, noop); // since the label symbol will mark it - DEFMAP(AST_Lambda, basic_sourcemap_gen); - DEFMAP(AST_Switch, basic_sourcemap_gen); - DEFMAP(AST_SwitchBranch, basic_sourcemap_gen); - DEFMAP(AST_BlockStatement, basic_sourcemap_gen); - DEFMAP(AST_Toplevel, noop); - DEFMAP(AST_New, basic_sourcemap_gen); - DEFMAP(AST_Try, basic_sourcemap_gen); - DEFMAP(AST_Catch, basic_sourcemap_gen); - DEFMAP(AST_Finally, basic_sourcemap_gen); - DEFMAP(AST_Definitions, basic_sourcemap_gen); - DEFMAP(AST_Constant, basic_sourcemap_gen); - DEFMAP(AST_ObjectSetter, function(self, output){ - output.add_mapping(self.start, self.key.name); - }); - DEFMAP(AST_ObjectGetter, function(self, output){ - output.add_mapping(self.start, self.key.name); - }); - DEFMAP(AST_ObjectProperty, function(self, output){ - output.add_mapping(self.start, self.key); + DEFMAP([ + AST_Array, + AST_BlockStatement, + AST_Catch, + AST_Constant, + AST_Debugger, + AST_Definitions, + AST_Directive, + AST_Finally, + AST_Jump, + AST_Lambda, + AST_New, + AST_Object, + AST_StatementWithBody, + AST_Symbol, + AST_Switch, + AST_SwitchBranch, + AST_Try, + ], function(output) { + output.add_mapping(this.start); + }); + + DEFMAP([ + AST_ObjectGetter, + AST_ObjectSetter, + ], function(output) { + output.add_mapping(this.start, this.key.name); + }); + + DEFMAP([ AST_ObjectProperty ], function(output) { + output.add_mapping(this.start, this.key); }); - })(); -- cgit v1.2.3