diff --git a/lib/output.js b/lib/output.js index 68906328..358e1931 100644 --- a/lib/output.js +++ b/lib/output.js @@ -103,7 +103,6 @@ function OutputStream(options) { var current_col = 0; var current_line = 1; - var current_pos = 0; var indentation = options.indent_start; var last; var line_end = 0; @@ -115,17 +114,17 @@ function OutputStream(options) { var might_need_semicolon; var need_newline_indented = false; var need_space = false; - var newline_insert = -1; + var output; var stack; - var OUTPUT; + var stored = ""; function reset() { last = ""; might_need_space = false; might_need_semicolon = false; stack = []; - var str = OUTPUT; - OUTPUT = ""; + var str = output; + output = ""; return str; } @@ -227,32 +226,30 @@ function OutputStream(options) { } : noop; 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); + stored += output.slice(0, line_end); + output = output.slice(line_end); + var new_col = output.length; + adjust_mappings(count, new_col - current_col); current_line += count; - current_pos += count; - current_col = right.length; - OUTPUT = left; - while (count--) OUTPUT += "\n"; - OUTPUT += right; + current_col = new_col; + while (count--) stored += "\n"; } - var fix_line = options.max_line_len ? function() { + var fix_line = options.max_line_len ? function(flush) { if (line_fixed) { if (current_col > options.max_line_len) { AST_Node.warn("Output exceeds {max_line_len} characters", options); } return; } - if (current_col > options.max_line_len) insert_newlines(1); - line_fixed = true; - flush_mappings(); + if (current_col > options.max_line_len) { + insert_newlines(1); + line_fixed = true; + } + if (line_fixed || flush) flush_mappings(); } : noop; - var requireSemicolonChars = makePredicate("( [ + * / - , ."); + var require_semicolon = makePredicate("( [ + * / - , ."); var print = options.beautify || options.comments @@ -276,32 +273,32 @@ function OutputStream(options) { space(); } } - newline_insert = -1; var prev = last.slice(-1); if (might_need_semicolon) { might_need_semicolon = false; - - if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") { - if (options.semicolons || requireSemicolonChars[ch]) { - OUTPUT += ";"; + if (prev == ":" && ch == "}" || prev != ";" && (!ch || ";}".indexOf(ch) < 0)) { + var need_semicolon = require_semicolon[ch]; + if (need_semicolon || options.semicolons) { + output += ";"; current_col++; - current_pos++; + if (!line_fixed) { + fix_line(); + if (line_fixed && !need_semicolon && output == ";") { + output = ""; + current_col = 0; + } + } + if (line_end == output.length - 1) line_end++; } else { fix_line(); - OUTPUT += "\n"; - current_pos++; + output += "\n"; current_line++; current_col = 0; - - if (/^\s+$/.test(str)) { - // reset the semicolon flag, since we didn't print one - // now and might still have to later - might_need_semicolon = true; - } + // reset the semicolon flag, since we didn't print one + // now and might still have to later + if (/^\s+$/.test(str)) might_need_semicolon = true; } - - if (!options.beautify) - might_need_space = false; + if (!options.beautify) might_need_space = false; } } @@ -312,9 +309,8 @@ function OutputStream(options) { || str == "--" && last == "!" || str == "in" && prev == "/" || last == "--" && ch == ">") { - OUTPUT += " "; + output += " "; current_col++; - current_pos++; } if (prev != "<" || str != "!") might_need_space = false; } @@ -324,14 +320,13 @@ function OutputStream(options) { token: mapping_token, name: mapping_name, line: current_line, - col: current_col + col: current_col, }); mapping_token = false; if (line_fixed) flush_mappings(); } - OUTPUT += str; - current_pos += str.length; + output += str; var a = str.split(/\r?\n/), n = a.length - 1; current_line += n; current_col += a[0].length; @@ -346,7 +341,7 @@ function OutputStream(options) { if (might_need_semicolon) { might_need_semicolon = false; if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") { - OUTPUT += ";"; + output += ";"; might_need_space = false; } } @@ -357,11 +352,11 @@ function OutputStream(options) { || str == "--" && last == "!" || str == "in" && prev == "/" || last == "--" && ch == ">") { - OUTPUT += " "; + output += " "; } if (prev != "<" || str != "!") might_need_space = false; } - OUTPUT += str; + output += str; last = str; }; @@ -385,18 +380,13 @@ function OutputStream(options) { var may_add_newline = options.max_line_len || options.preserve_line ? function() { fix_line(); - line_end = OUTPUT.length; + 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++; + print("\n"); + line_end = output.length; } : may_add_newline; var semicolon = options.beautify ? function() { @@ -452,13 +442,12 @@ function OutputStream(options) { } : noop; function get() { - if (!line_fixed) fix_line(); - return OUTPUT; + if (!line_fixed) fix_line(true); + return stored + output; } function has_nlb() { - var index = OUTPUT.lastIndexOf("\n"); - return /^ *$/.test(OUTPUT.slice(index + 1)); + return /(^|\n) *$/.test(output); } function pad_comment(token, force) { @@ -515,7 +504,7 @@ function OutputStream(options) { scan.walk(tw); } - if (current_pos == 0) { + if (current_line == 1 && current_col == 0) { if (comments.length > 0 && options.shebang && comments[0].type == "comment5") { print("#!" + comments.shift().value + "\n"); indent(); @@ -559,19 +548,17 @@ function OutputStream(options) { return !/comment[134]/.test(c.type); }))) return; comments._dumped = self; - var insert = OUTPUT.length; comments.filter(comment_filter, node).forEach(function(comment, index) { pad_comment(comment, index || !tail); print_comment(comment); }); - if (OUTPUT.length > insert) newline_insert = insert; } return { get : get, reset : reset, indent : indent, - should_break : options.width ? function() { + should_break : options.beautify && options.width ? function() { return current_col - indentation >= options.width; } : return_false, has_parens : function() { return last.slice(-1) == "(" }, diff --git a/test/compress/max_line_len.js b/test/compress/max_line_len.js index 5be4e059..c72fa5ef 100644 --- a/test/compress/max_line_len.js +++ b/test/compress/max_line_len.js @@ -37,6 +37,51 @@ just_enough: { expect_warnings: [] } +drop_semicolon: { + beautify = { + max_line_len: 5, + semicolons: true, + } + input: { + var a; + console.log(a || 42); + } + expect_exact: [ + "var a", + "console.log(", + "a||42", + ");", + ] + expect_stdout: "42" + expect_warnings: [ + "WARN: Output exceeds 5 characters", + ] +} + +template_newline: { + beautify = { + max_line_len: 2, + } + input: { + console.log(`foo +bar`); + } + expect_exact: [ + "console.log(", + "`foo", + "bar`", + ");", + ] + expect_stdout: [ + "foo", + "bar", + ] + expect_warnings: [ + "WARN: Output exceeds 2 characters", + ] + node_version: ">=4" +} + issue_304: { beautify = { max_line_len: 10, diff --git a/test/compress/preserve_line.js b/test/compress/preserve_line.js index 5b1638ca..7c859ec0 100644 --- a/test/compress/preserve_line.js +++ b/test/compress/preserve_line.js @@ -97,10 +97,10 @@ return_5: { } expect_exact: [ "_is_selected=function(tags,slug){", - "var ref", + "var ref;", "", "", - ";return null!=(ref=_.find(tags,{slug:slug}))?ref.selected:void 0};", + "return null!=(ref=_.find(tags,{slug:slug}))?ref.selected:void 0};", ] } @@ -146,10 +146,10 @@ return_7: { } expect_exact: [ "_is_selected=function(e,l){", - "var n", + "var n;", "", "", - ";return null!=(n=_.find(e,{slug:l}))?n.selected:void 0};", + "return null!=(n=_.find(e,{slug:l}))?n.selected:void 0};", ] } diff --git a/test/input/issue-505/output.js b/test/input/issue-505/output.js index d81d0f92..5627c00c 100644 --- a/test/input/issue-505/output.js +++ b/test/input/issue-505/output.js @@ -1,5 +1,5 @@ function test(a){ -"aaaaaaaaaaaaaaaa" -;a(err,data),a(err, +"aaaaaaaaaaaaaaaa"; +a(err,data),a(err, data)} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsS0FBS0M7O0NBRVZBLEVBQVNDLElBQUtDLE1BQ2RGLEVBQVNDO0FBQUtDIn0= \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0E7SEFBS0M7QUFFVkE7aEJBQVNDLElBQUtDLE1BQ2RGLEVBQVNDLElBQUtDIn0= \ No newline at end of file