speed up `has_parens()` (take 2) (#3052)
authorAlex Lam S.L <alexlamsl@gmail.com>
Wed, 4 Apr 2018 20:12:04 +0000 (04:12 +0800)
committerGitHub <noreply@github.com>
Wed, 4 Apr 2018 20:12:04 +0000 (04:12 +0800)
fixes #3050

lib/output.js
test/mocha/parentheses.js [moved from test/mocha/new.js with 82% similarity]

index cad6fd8..0f34904 100644 (file)
@@ -197,6 +197,7 @@ function OutputStream(options) {
 
     /* -----[ beautification/minification ]----- */
 
+    var has_parens = false;
     var might_need_space = false;
     var might_need_semicolon = false;
     var might_add_newline = 0;
@@ -340,6 +341,7 @@ function OutputStream(options) {
         }
 
         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;
@@ -576,7 +578,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 OUTPUT[OUTPUT.length - 1] == "(" },
+        has_parens      : function() { return has_parens },
         newline         : newline,
         print           : print,
         space           : space,
similarity index 82%
rename from test/mocha/new.js
rename to test/mocha/parentheses.js
index 8f653f7..a3ef860 100644 (file)
@@ -1,7 +1,7 @@
 var assert = require("assert");
 var uglify = require("../../");
 
-describe("New", function() {
+describe("parentheses", function() {
     it("Should add trailing parentheses for new expressions with zero arguments in beautify mode", function() {
         var tests = [
             "new x(1);",
@@ -83,4 +83,23 @@ describe("New", function() {
             );
         }
     });
-});
\ No newline at end of file
+
+    it("Should compress leading parenthesis with reasonable performance", function() {
+        this.timeout(30000);
+        var code = [
+            "({}?0:1)&&x();",
+            "(function(){}).name;",
+        ];
+        for (var i = 16; --i >= 0;) {
+            [].push.apply(code, code);
+        }
+        code = code.join("");
+        var result = uglify.minify(code, {
+            compress: false,
+            mangle: false,
+        });
+        if (result.error) throw result.error;
+        // Dismal performance for `assert.strictEqual()` in Node.js 6
+        assert.ok(result.code === code);
+    });
+});