speed up `OutputStream` (#4844)
authorAlex Lam S.L <alexlamsl@gmail.com>
Tue, 6 Apr 2021 18:57:23 +0000 (19:57 +0100)
committerGitHub <noreply@github.com>
Tue, 6 Apr 2021 18:57:23 +0000 (02:57 +0800)
lib/output.js

index e200979..e8fd1cf 100644 (file)
@@ -101,44 +101,32 @@ function OutputStream(options) {
         }
     }
 
-    var OUTPUT;
-    var current_col;
-    var current_line;
-    var current_pos;
-    var has_parens;
-    var indentation;
+    var current_col = 0;
+    var current_line = 1;
+    var current_pos = 0;
+    var indentation = options.indent_start;
     var last;
-    var line_end;
-    var line_fixed;
-    var mappings;
+    var line_end = 0;
+    var line_fixed = true;
+    var mappings = options.source_map && [];
     var mapping_name;
     var mapping_token;
     var might_need_space;
     var might_need_semicolon;
-    var need_newline_indented;
-    var need_space;
-    var newline_insert;
+    var need_newline_indented = false;
+    var need_space = false;
+    var newline_insert = -1;
     var stack;
+    var OUTPUT;
 
     function reset() {
-        OUTPUT = "";
-        current_col = 0;
-        current_line = 1;
-        current_pos = 0;
-        has_parens = false;
-        indentation = options.indent_start;
         last = "";
-        line_end = 0;
-        line_fixed = true;
-        mappings = options.source_map && [];
-        mapping_name = null;
-        mapping_token = null;
         might_need_space = false;
         might_need_semicolon = false;
-        need_newline_indented = false;
-        need_space = false;
-        newline_insert = -1;
         stack = [];
+        var str = OUTPUT;
+        OUTPUT = "";
+        return str;
     }
 
     reset();
@@ -266,8 +254,14 @@ function OutputStream(options) {
 
     var requireSemicolonChars = makePredicate("( [ + * / - , .");
 
-    function print(str) {
-        str = String(str);
+    var print = options.beautify
+        || options.comments
+        || options.max_line_len
+        || options.preserve_line
+        || options.shebang
+        || !options.semicolons
+        || options.source_map
+        || options.width ? function(str) {
         var ch = str.charAt(0);
         if (need_newline_indented && ch) {
             need_newline_indented = false;
@@ -337,7 +331,6 @@ function OutputStream(options) {
         }
 
         OUTPUT += str;
-        has_parens = str.slice(-1) == "(";
         current_pos += str.length;
         var a = str.split(/\r?\n/), n = a.length - 1;
         current_line += n;
@@ -347,7 +340,30 @@ function OutputStream(options) {
             current_col = a[n].length;
         }
         last = str;
-    }
+    } : function(str) {
+        var ch = str.charAt(0);
+        var prev = last.slice(-1);
+        if (might_need_semicolon) {
+            might_need_semicolon = false;
+            if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
+                OUTPUT += ";";
+                might_need_space = false;
+            }
+        }
+        if (might_need_space) {
+            if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
+                || (ch == "/" && ch == prev)
+                || ((ch == "+" || ch == "-") && ch == last)
+                || str == "--" && last == "!"
+                || str == "in" && prev == "/"
+                || last == "--" && ch == ">") {
+                OUTPUT += " ";
+            }
+            if (prev != "<" || str != "!") might_need_space = false;
+        }
+        OUTPUT += str;
+        last = str;
+    };
 
     var space = options.beautify ? function() {
         print(" ");
@@ -551,10 +567,10 @@ function OutputStream(options) {
         get             : get,
         reset           : reset,
         indent          : indent,
-        should_break    : function() {
-            return options.width && current_col - indentation >= options.width;
-        },
-        has_parens      : function() { return has_parens },
+        should_break    : options.width ? function() {
+            return current_col - indentation >= options.width;
+        } : return_false,
+        has_parens      : function() { return last.slice(-1) == "(" },
         newline         : newline,
         print           : print,
         space           : space,
@@ -577,11 +593,8 @@ function OutputStream(options) {
         with_square     : with_square,
         add_mapping     : add_mapping,
         option          : function(opt) { return options[opt] },
-        prepend_comments: prepend_comments,
-        append_comments : comment_filter === return_false ? noop : append_comments,
-        line            : function() { return current_line },
-        col             : function() { return current_col },
-        pos             : function() { return current_pos },
+        prepend_comments: options.comments || options.shebang ? prepend_comments : noop,
+        append_comments : options.comments ? append_comments : noop,
         push_node       : function(node) { stack.push(node) },
         pop_node        : options.preserve_line ? function() {
             var node = stack.pop();
@@ -628,9 +641,9 @@ function OutputStream(options) {
     });
     var readonly = OutputStream({
         inline_script: false,
+        shebang: false,
+        width: false,
     });
-    readonly.prepend_comments = noop;
-    readonly.should_break = return_false;
     AST_Node.DEFMETHOD("print_to_string", function(options) {
         if (options) {
             var stream = OutputStream(options);
@@ -638,9 +651,7 @@ function OutputStream(options) {
             return stream.get();
         }
         this.print(readonly);
-        var str = readonly.get();
-        readonly.reset();
-        return str;
+        return readonly.reset();
     });
 
     /* -----[ PARENTHESES ]----- */
@@ -1489,11 +1500,7 @@ function OutputStream(options) {
             output.print_string(prop);
             output.print("]");
         } else {
-            if (expr instanceof AST_Number && expr.value >= 0) {
-                if (!/[xa-f.)]/i.test(output.last())) {
-                    output.print(".");
-                }
-            }
+            if (expr instanceof AST_Number && !/[ex.)]/i.test(output.last())) output.print(".");
             output.print(".");
             // the name after dot would be mapped about here.
             output.add_mapping(self.end);
@@ -1743,7 +1750,7 @@ function OutputStream(options) {
         output.print("`");
     });
     DEFPRINT(AST_Constant, function(output) {
-        output.print(this.value);
+        output.print("" + this.value);
     });
     DEFPRINT(AST_String, function(output) {
         output.print_string(this.value, this.quote);
@@ -1799,7 +1806,7 @@ function OutputStream(options) {
     function force_statement(stat, output) {
         if (output.option("braces") && !(stat instanceof AST_Const || stat instanceof AST_Let)) {
             make_block(stat, output);
-        } else if (!stat || stat instanceof AST_EmptyStatement) {
+        } else if (stat instanceof AST_EmptyStatement) {
             output.force_semicolon();
         } else {
             stat.print(output);
@@ -1850,11 +1857,11 @@ function OutputStream(options) {
     }
 
     function make_block(stmt, output) {
-        if (!stmt || stmt instanceof AST_EmptyStatement)
-            output.print("{}");
-        else if (stmt instanceof AST_BlockStatement)
+        if (stmt instanceof AST_EmptyStatement) {
+            print_braced_empty(stmt, output);
+        } 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();