clean up `OutputStream` (#4842)
authorAlex Lam S.L <alexlamsl@gmail.com>
Tue, 6 Apr 2021 13:34:27 +0000 (14:34 +0100)
committerGitHub <noreply@github.com>
Tue, 6 Apr 2021 13:34:27 +0000 (21:34 +0800)
lib/output.js
test/ufuzz/index.js

index fef57bc..e200979 100644 (file)
@@ -49,8 +49,6 @@ function is_some_comments(comment) {
 }
 
 function OutputStream(options) {
-
-    var readonly = !options;
     options = defaults(options, {
         annotations      : false,
         ascii_only       : false,
@@ -103,12 +101,47 @@ function OutputStream(options) {
         }
     }
 
-    var indentation = options.indent_start;
-    var current_col = 0;
-    var current_line = 1;
-    var current_pos = 0;
-    var OUTPUT = "";
+    var OUTPUT;
+    var current_col;
+    var current_line;
+    var current_pos;
+    var has_parens;
+    var indentation;
+    var last;
+    var line_end;
+    var line_fixed;
+    var mappings;
+    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 stack;
+
+    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 = [];
+    }
 
+    reset();
     var to_utf8 = options.ascii_only ? function(str, identifier) {
         if (identifier) str = str.replace(/[\ud800-\udbff][\udc00-\udfff]/g, function(ch) {
             return "\\u{" + (ch.charCodeAt(0) - 0xd7c0 << 10 | ch.charCodeAt(1) - 0xdc00).toString(16) + "}";
@@ -141,6 +174,25 @@ function OutputStream(options) {
         return j == 0 ? str : s + str.slice(j);
     };
 
+    function quote_single(str) {
+        return "'" + str.replace(/\x27/g, "\\'") + "'";
+    }
+
+    function quote_double(str) {
+        return '"' + str.replace(/\x22/g, '\\"') + '"';
+    }
+
+    var quote_string = [
+        function(str, quote, dq, sq) {
+            return dq > sq ? quote_single(str) : quote_double(str);
+        },
+        quote_single,
+        quote_double,
+        function(str, quote) {
+            return quote == "'" ? quote_single(str) : quote_double(str);
+        },
+    ][options.quote_style];
+
     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) {
@@ -162,54 +214,11 @@ function OutputStream(options) {
             }
             return s;
         });
-        function quote_single() {
-            return "'" + str.replace(/\x27/g, "\\'") + "'";
-        }
-        function quote_double() {
-            return '"' + str.replace(/\x22/g, '\\"') + '"';
-        }
-        str = to_utf8(str);
-        switch (options.quote_style) {
-          case 1:
-            return quote_single();
-          case 2:
-            return quote_double();
-          case 3:
-            return quote == "'" ? quote_single() : quote_double();
-          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(/<\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;
+        return quote_string(to_utf8(str), quote, dq, sq);
     }
 
     /* -----[ 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 need_newline_indented = false;
-    var need_space = false;
-    var newline_insert = -1;
-    var last = "";
-    var mapping_token, mapping_name, mappings = options.source_map && [];
-
     var adjust_mappings = mappings ? function(line, col) {
         mappings.forEach(function(mapping) {
             mapping.line += line;
@@ -351,14 +360,12 @@ function OutputStream(options) {
         print(repeat_string(" ", half ? indentation - (options.indent_level >> 1) : indentation));
     } : noop;
 
-    var with_indent = options.beautify ? function(col, cont) {
-        if (col === true) col = next_indent();
+    var with_indent = options.beautify ? function(cont) {
         var save_indentation = indentation;
-        indentation = col;
-        var ret = cont();
+        indentation += options.indent_level;
+        cont();
         indentation = save_indentation;
-        return ret;
-    } : function(col, cont) { return cont() };
+    } : function(cont) { cont() };
 
     var may_add_newline = options.max_line_len || options.preserve_line ? function() {
         fix_line();
@@ -387,41 +394,28 @@ function OutputStream(options) {
         print(";");
     }
 
-    function next_indent() {
-        return indentation + options.indent_level;
-    }
-
     function with_block(cont) {
-        var ret;
         print("{");
         newline();
-        with_indent(next_indent(), function() {
-            ret = cont();
-        });
+        with_indent(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();
+        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();
+        cont();
         may_add_newline();
         print("]");
-        return ret;
     }
 
     function comma() {
@@ -553,12 +547,11 @@ function OutputStream(options) {
         if (OUTPUT.length > insert) newline_insert = insert;
     }
 
-    var stack = [];
     return {
         get             : get,
-        toString        : get,
+        reset           : reset,
         indent          : indent,
-        should_break    : readonly ? noop : function() {
+        should_break    : function() {
             return options.width && current_col - indentation >= options.width;
         },
         has_parens      : function() { return has_parens },
@@ -571,17 +564,21 @@ function OutputStream(options) {
         semicolon       : semicolon,
         force_semicolon : force_semicolon,
         to_utf8         : to_utf8,
-        print_name      : function(name) { print(make_name(name)) },
-        print_string    : function(str, quote) { print(encode_string(str, quote)) },
-        next_indent     : next_indent,
+        print_name      : function(name) { print(to_utf8(name.toString(), true)) },
+        print_string    : options.inline_script ? function(str, quote) {
+            str = make_string(str, quote).replace(/<\x2f(script)([>\/\t\n\f\r ])/gi, "<\\/$1$2");
+            print(str.replace(/\x3c!--/g, "\\x3c!--").replace(/--\x3e/g, "--\\x3e"));
+        } : function(str, quote) {
+            print(make_string(str, quote));
+        },
         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] },
-        prepend_comments: readonly ? noop : prepend_comments,
-        append_comments : readonly || comment_filter === return_false ? noop : append_comments,
+        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 },
@@ -629,10 +626,21 @@ function OutputStream(options) {
             stream.append_comments(self);
         }
     });
+    var readonly = OutputStream({
+        inline_script: false,
+    });
+    readonly.prepend_comments = noop;
+    readonly.should_break = return_false;
     AST_Node.DEFMETHOD("print_to_string", function(options) {
-        var s = OutputStream(options);
-        this.print(s);
-        return s.get();
+        if (options) {
+            var stream = OutputStream(options);
+            this.print(stream);
+            return stream.get();
+        }
+        this.print(readonly);
+        var str = readonly.get();
+        readonly.reset();
+        return str;
     });
 
     /* -----[ PARENTHESES ]----- */
@@ -915,7 +923,7 @@ function OutputStream(options) {
     });
     function print_braced_empty(self, output) {
         output.print("{");
-        output.with_indent(output.next_indent(), function() {
+        output.with_indent(function() {
             output.append_comments(self, true);
         });
         output.print("}");
index 7eadc9a..5c6c262 100644 (file)
@@ -206,6 +206,7 @@ var VALUES = [
 ];
 VALUES = VALUES.concat(VALUES);
 VALUES = VALUES.concat(VALUES);
+VALUES = VALUES.concat(VALUES);
 if (SUPPORT.bigint) VALUES = VALUES.concat([
     "(!0o644n)",
     "([3n][0] > 2)",
@@ -215,6 +216,7 @@ if (SUPPORT.bigint) VALUES = VALUES.concat([
 VALUES = VALUES.concat(VALUES);
 VALUES = VALUES.concat(VALUES);
 VALUES = VALUES.concat(VALUES);
+VALUES = VALUES.concat(VALUES);
 VALUES.push("import.meta");
 
 var BINARY_OPS = [