diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:01:11 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:02:09 +0200 |
commit | 363723fc84f7b8477592e0105aeb331ec9a017af (patch) | |
tree | 29f92724f34131bac64d6a318dd7e30612e631c7 /node_modules/uglify-js/lib/output.js | |
parent | 5634e77ad96bfe1818f6b6ee70b7379652e5487f (diff) |
node_modules
Diffstat (limited to 'node_modules/uglify-js/lib/output.js')
-rw-r--r-- | node_modules/uglify-js/lib/output.js | 267 |
1 files changed, 144 insertions, 123 deletions
diff --git a/node_modules/uglify-js/lib/output.js b/node_modules/uglify-js/lib/output.js index 0731fb492..4c873f10d 100644 --- a/node_modules/uglify-js/lib/output.js +++ b/node_modules/uglify-js/lib/output.js @@ -57,6 +57,7 @@ function OutputStream(options) { beautify : false, bracketize : false, comments : false, + ie8 : false, indent_level : 4, indent_start : 0, inline_script : true, @@ -66,12 +67,10 @@ function OutputStream(options) { preserve_line : false, quote_keys : false, quote_style : 0, - screw_ie8 : true, semicolons : true, shebang : true, source_map : null, - space_colon : true, - unescape_regexps : false, + webkit : false, width : 80, wrap_iife : false, }, true); @@ -110,7 +109,7 @@ function OutputStream(options) { var current_pos = 0; var OUTPUT = ""; - function to_ascii(str, identifier) { + var to_utf8 = options.ascii_only ? function(str, identifier) { return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) { var code = ch.charCodeAt(0).toString(16); if (code.length <= 2 && !identifier) { @@ -121,6 +120,12 @@ function OutputStream(options) { return "\\u" + code; } }); + } : 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); + }); }; function make_string(str, quote) { @@ -136,7 +141,7 @@ function OutputStream(options) { case "\t": return "\\t"; case "\b": return "\\b"; case "\f": return "\\f"; - case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B"; + case "\x0B": return options.ie8 ? "\\x0B" : "\\v"; case "\u2028": return "\\u2028"; case "\u2029": return "\\u2029"; case "\ufeff": return "\\ufeff"; @@ -151,7 +156,7 @@ function OutputStream(options) { function quote_double() { return '"' + str.replace(/\x22/g, '\\"') + '"'; } - if (options.ascii_only) str = to_ascii(str); + str = to_utf8(str); switch (options.quote_style) { case 1: return quote_single(); @@ -176,8 +181,7 @@ function OutputStream(options) { function make_name(name) { name = name.toString(); - if (options.ascii_only) - name = to_ascii(name, true); + name = to_utf8(name, true); return name; }; @@ -191,12 +195,43 @@ function OutputStream(options) { var might_need_semicolon = false; var might_add_newline = 0; var last = ""; + var mapping_token, mapping_name, mappings = options.source_map && []; + + var do_add_mapping = mappings ? function() { + mappings.forEach(function(mapping) { + try { + options.source_map.add( + mapping.token.file, + mapping.line, mapping.col, + mapping.token.line, mapping.token.col, + !mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name + ); + } catch(ex) { + AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", { + file: mapping.token.file, + line: mapping.token.line, + col: mapping.token.col, + cline: mapping.line, + ccol: mapping.col, + name: mapping.name || "" + }) + } + }); + 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++; @@ -206,7 +241,10 @@ function OutputStream(options) { AST_Node.warn("Output exceeds {max_line_len} characters", options); } } - might_add_newline = 0; + if (might_add_newline) { + might_add_newline = 0; + do_add_mapping(); + } } : noop; var requireSemicolonChars = makePredicate("( [ + * / - , ."); @@ -266,6 +304,18 @@ function OutputStream(options) { } might_need_space = false; } + + if (mapping_token) { + mappings.push({ + token: mapping_token, + name: mapping_name, + line: current_line, + col: current_col + }); + mapping_token = false; + if (!might_add_newline) do_add_mapping(); + } + OUTPUT += str; current_pos += str.length; var a = str.split(/\r?\n/), n = a.length - 1; @@ -357,27 +407,12 @@ function OutputStream(options) { function colon() { print(":"); - if (options.space_colon) space(); + 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) { - 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 || "" - }) - } + var add_mapping = mappings ? function(token, name) { + mapping_token = token; + mapping_name = name; } : noop; function get() { @@ -403,7 +438,7 @@ function OutputStream(options) { last : function() { return last }, semicolon : semicolon, force_semicolon : force_semicolon, - to_ascii : to_ascii, + to_utf8 : to_utf8, print_name : function(name) { print(make_name(name)) }, print_string : function(str, quote, escape_directive) { var encoded = encode_string(str, quote); @@ -471,6 +506,7 @@ function OutputStream(options) { use_asm = prev_use_asm; } }); + AST_Node.DEFMETHOD("_print", AST_Node.prototype.print); AST_Node.DEFMETHOD("print_to_string", function(options){ var s = OutputStream(options); @@ -568,6 +604,13 @@ function OutputStream(options) { return true; } + if (output.option('webkit')) { + var p = output.parent(); + 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; @@ -588,7 +631,7 @@ function OutputStream(options) { || p instanceof AST_Call && p.expression === this; }); - PARENS(AST_Seq, 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) @@ -634,14 +677,15 @@ function OutputStream(options) { // parens around it too, otherwise the call will be // interpreted as passing the arguments to the upper New // expression. - try { - this.walk(new TreeWalker(function(node){ - if (node instanceof AST_Call) throw p; - })); - } catch(ex) { - if (ex !== p) throw ex; - return true; - } + var parens = false; + this.walk(new TreeWalker(function(node) { + if (parens || node instanceof AST_Scope) return true; + if (node instanceof AST_Call) { + parens = true; + return true; + } + })); + return parens; } }); @@ -677,7 +721,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) @@ -902,7 +946,7 @@ function OutputStream(options) { function make_then(self, output) { var b = self.body; if (output.option("bracketize") - || !output.option("screw_ie8") && b instanceof AST_Do) + || output.option("ie8") && b instanceof AST_Do) return make_block(b, output); // The squeezer replaces "block"-s that contain only a single // statement with the statement itself; technically, the AST @@ -1033,24 +1077,19 @@ function OutputStream(options) { DEFPRINT(AST_Var, function(self, output){ self._do_print(output, "var"); }); - DEFPRINT(AST_Const, function(self, output){ - self._do_print(output, "const"); - }); function parenthesize_for_noin(node, output, noin) { - if (!noin) node.print(output); - else try { - // need to take some precautions here: - // https://github.com/mishoo/UglifyJS2/issues/60 - node.walk(new TreeWalker(function(node){ - if (node instanceof AST_Binary && node.operator == "in") - throw output; - })); - node.print(output); - } catch(ex) { - if (ex !== output) throw ex; - node.print(output, true); - } + var parens = false; + // need to take some precautions here: + // https://github.com/mishoo/UglifyJS2/issues/60 + if (noin) node.walk(new TreeWalker(function(node) { + if (parens || node instanceof AST_Scope) return true; + if (node instanceof AST_Binary && node.operator == "in") { + parens = true; + return true; + } + })); + node.print(output, parens); }; DEFPRINT(AST_VarDef, function(self, output){ @@ -1070,6 +1109,9 @@ function OutputStream(options) { self.expression.print(output); if (self instanceof AST_New && !need_constructor_parens(self, output)) return; + if (self.expression instanceof AST_Lambda) { + output.add_mapping(self.start); + } output.with_parens(function(){ self.args.forEach(function(expr, i){ if (i) output.comma(); @@ -1083,18 +1125,19 @@ function OutputStream(options) { AST_Call.prototype._codegen(self, output); }); - AST_Seq.DEFMETHOD("_do_print", function(output){ - this.car.print(output); - if (this.cdr) { - output.comma(); - if (output.should_break()) { - output.newline(); - output.indent(); + AST_Sequence.DEFMETHOD("_do_print", function(output){ + this.expressions.forEach(function(node, index) { + if (index > 0) { + output.comma(); + if (output.should_break()) { + output.newline(); + output.indent(); + } } - this.cdr.print(output); - } + node.print(output); + }); }); - DEFPRINT(AST_Seq, function(self, output){ + DEFPRINT(AST_Sequence, function(self, output){ self._do_print(output); // var p = output.parent(); // if (p instanceof AST_Statement) { @@ -1108,15 +1151,23 @@ function OutputStream(options) { DEFPRINT(AST_Dot, function(self, output){ var expr = self.expression; expr.print(output); - if (expr instanceof AST_Number && expr.getValue() >= 0) { - if (!/[xa-f.)]/i.test(output.last())) { - output.print("."); + var prop = self.property; + if (output.option("ie8") && RESERVED_WORDS(prop)) { + output.print("["); + output.add_mapping(self.end); + output.print_string(prop); + output.print("]"); + } else { + if (expr instanceof AST_Number && expr.getValue() >= 0) { + if (!/[xa-f.)]/i.test(output.last())) { + output.print("."); + } } + output.print("."); + // the name after dot would be mapped about here. + output.add_mapping(self.end); + output.print_name(prop); } - output.print("."); - // the name after dot would be mapped about here. - output.add_mapping(self.end); - output.print_name(self.property); }); DEFPRINT(AST_Sub, function(self, output){ self.expression.print(output); @@ -1207,9 +1258,8 @@ function OutputStream(options) { }); else output.print("{}"); }); - DEFPRINT(AST_ObjectKeyVal, function(self, output){ - var key = self.key; - var quote = self.quote; + + function print_property_name(key, quote, output) { if (output.option("quote_keys")) { output.print_string(key + ""); } else if ((typeof key == "number" @@ -1217,7 +1267,7 @@ function OutputStream(options) { && +key + "" == key) && parseFloat(key) >= 0) { output.print(make_num(key)); - } else if (RESERVED_WORDS(key) ? output.option("screw_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 { @@ -1226,20 +1276,24 @@ function OutputStream(options) { } else { output.print_string(key, quote); } + } + + DEFPRINT(AST_ObjectKeyVal, function(self, output){ + print_property_name(self.key, self.quote, output); output.colon(); self.value.print(output); }); - DEFPRINT(AST_ObjectSetter, function(self, output){ - output.print("set"); + AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, output) { + output.print(type); output.space(); - self.key.print(output); - self.value._do_print(output, true); + print_property_name(this.key.name, this.quote, output); + this.value._do_print(output, true); + }); + DEFPRINT(AST_ObjectSetter, function(self, output){ + self._print_getter_setter("set", output); }); DEFPRINT(AST_ObjectGetter, function(self, output){ - output.print("get"); - output.space(); - self.key.print(output); - self.value._do_print(output, true); + self._print_getter_setter("get", output); }); DEFPRINT(AST_Symbol, function(self, output){ var def = self.definition(); @@ -1263,46 +1317,13 @@ function OutputStream(options) { } }); - function regexp_safe_literal(code) { - return [ - 0x5c , // \ - 0x2f , // / - 0x2e , // . - 0x2b , // + - 0x2a , // * - 0x3f , // ? - 0x28 , // ( - 0x29 , // ) - 0x5b , // [ - 0x5d , // ] - 0x7b , // { - 0x7d , // } - 0x24 , // $ - 0x5e , // ^ - 0x3a , // : - 0x7c , // | - 0x21 , // ! - 0x0a , // \n - 0x0d , // \r - 0x00 , // \0 - 0xfeff , // Unicode BOM - 0x2028 , // unicode "line separator" - 0x2029 , // unicode "paragraph separator" - ].indexOf(code) < 0; - }; - DEFPRINT(AST_RegExp, function(self, output){ - var str = self.getValue().toString(); - if (output.option("ascii_only")) { - str = output.to_ascii(str); - } else if (output.option("unescape_regexps")) { - str = str.split("\\\\").map(function(str){ - return str.replace(/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g, function(s){ - var code = parseInt(s.substr(2), 16); - return regexp_safe_literal(code) ? String.fromCharCode(code) : s; - }); - }).join("\\\\"); + var regexp = self.getValue(); + var str = regexp.toString(); + if (regexp.raw_source) { + str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/")); } + str = output.to_utf8(str); output.print(str); var p = output.parent(); if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self) |