parse `mangle.properties.regex` in `--config-file` properly (#3337)
authorAlex Lam S.L <alexlamsl@gmail.com>
Thu, 14 Mar 2019 16:20:20 +0000 (00:20 +0800)
committerGitHub <noreply@github.com>
Thu, 14 Mar 2019 16:20:20 +0000 (00:20 +0800)
fixes #3315

bin/uglifyjs
lib/parse.js
test/input/issue-3315/config.json [new file with mode: 0644]
test/input/issue-3315/input.js [new file with mode: 0644]
test/mocha/cli.js
test/mocha/comments.js
test/mocha/directives.js
test/mocha/getter-setter.js
test/mocha/minify.js

index 62c7beb..bee6b6a 100755 (executable)
@@ -56,6 +56,11 @@ program.option("--wrap <name>", "Embed everything as a function with â€śexports
 program.arguments("[files...]").parseArgv(process.argv);
 if (program.configFile) {
     options = JSON.parse(read_file(program.configFile));
+    if (options.mangle && options.mangle.properties && options.mangle.properties.regex) {
+        options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, {
+            expression: true
+        }).getValue();
+    }
 }
 if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
     fatal("ERROR: cannot write source map to STDOUT");
@@ -337,17 +342,9 @@ function parse_js(flag) {
     return function(value, options) {
         options = options || {};
         try {
-            UglifyJS.minify(value, {
-                parse: {
-                    expression: true
-                },
-                compress: false,
-                mangle: false,
-                output: {
-                    ast: true,
-                    code: false
-                }
-            }).ast.walk(new UglifyJS.TreeWalker(function(node) {
+            UglifyJS.parse(value, {
+                expression: true
+            }).walk(new UglifyJS.TreeWalker(function(node) {
                 if (node instanceof UglifyJS.AST_Assign) {
                     var name = node.left.print_to_string();
                     var value = node.right;
index 29df370..a58557d 100644 (file)
@@ -758,17 +758,21 @@ function parse($TEXT, options) {
         croak(msg, token.line, token.col);
     }
 
+    function token_to_string(type, value) {
+        return type + (value === undefined ? "" : " «" + value + "»");
+    }
+
     function unexpected(token) {
         if (token == null)
             token = S.token;
-        token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
+        token_error(token, "Unexpected token: " + token_to_string(token.type, token.value));
     }
 
     function expect_token(type, val) {
         if (is(type, val)) {
             return next();
         }
-        token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
+        token_error(S.token, "Unexpected token: " + token_to_string(S.token.type, S.token.value) + ", expected: " + token_to_string(type, val));
     }
 
     function expect(punc) {
@@ -788,7 +792,7 @@ function parse($TEXT, options) {
 
     function semicolon(optional) {
         if (is("punc", ";")) next();
-        else if (!optional && !can_insert_semicolon()) unexpected();
+        else if (!optional && !can_insert_semicolon()) expect_token("punc", ";");
     }
 
     function parenthesised() {
@@ -1069,7 +1073,7 @@ function parse($TEXT, options) {
         var in_statement = ctor === AST_Defun;
         var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
         if (in_statement && !name)
-            unexpected();
+            expect_token("name");
         if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
             unexpected(prev());
         expect("(");
@@ -1119,7 +1123,7 @@ function parse($TEXT, options) {
         expect("{");
         var a = [];
         while (!is("punc", "}")) {
-            if (is("eof")) unexpected();
+            if (is("eof")) expect_token("punc", "}");
             a.push(statement(strict_defun));
         }
         next();
@@ -1130,7 +1134,7 @@ function parse($TEXT, options) {
         expect("{");
         var a = [], cur = null, branch = null, tmp;
         while (!is("punc", "}")) {
-            if (is("eof")) unexpected();
+            if (is("eof")) expect_token("punc", "}");
             if (is("keyword", "case")) {
                 if (branch) branch.end = prev();
                 cur = [];
@@ -1141,8 +1145,7 @@ function parse($TEXT, options) {
                 });
                 a.push(branch);
                 expect(":");
-            }
-            else if (is("keyword", "default")) {
+            } else if (is("keyword", "default")) {
                 if (branch) branch.end = prev();
                 cur = [];
                 branch = new AST_Default({
@@ -1150,8 +1153,7 @@ function parse($TEXT, options) {
                     body  : cur
                 });
                 a.push(branch);
-            }
-            else {
+            } else {
                 if (!cur) unexpected();
                 cur.push(statement());
             }
@@ -1420,10 +1422,10 @@ function parse($TEXT, options) {
     }
 
     function as_name() {
-        var tmp = S.token;
-        if (tmp.type != "name") unexpected();
+        if (!is("name")) expect_token("name");
+        var name = S.token.value;
         next();
-        return tmp.value;
+        return name;
     }
 
     function _make_symbol(type) {
@@ -1625,6 +1627,7 @@ function parse($TEXT, options) {
     }
 
     if (options.expression) {
+        handle_regexp();
         return expression(true);
     }
 
diff --git a/test/input/issue-3315/config.json b/test/input/issue-3315/config.json
new file mode 100644 (file)
index 0000000..4bcbaed
--- /dev/null
@@ -0,0 +1,8 @@
+{\r
+    "compress": false,\r
+    "mangle": {\r
+        "properties": {\r
+            "regex": "/^_/"\r
+        }\r
+    }\r
+}\r
diff --git a/test/input/issue-3315/input.js b/test/input/issue-3315/input.js
new file mode 100644 (file)
index 0000000..5013fc2
--- /dev/null
@@ -0,0 +1,8 @@
+function f() {
+    "aaaaaaaaaa";
+    var o = {
+        prop: 1,
+        _int: 2,
+    };
+    return o.prop + o._int;
+}
index 1e27f64..af537f3 100644 (file)
@@ -257,7 +257,7 @@ describe("bin/uglifyjs", function() {
             assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
             assert.strictEqual(lines[1], "function f(a{}");
             assert.strictEqual(lines[2], "            ^");
-            assert.strictEqual(lines[3], "ERROR: Unexpected token punc «{», expected punc «,»");
+            assert.strictEqual(lines[3], "ERROR: Unexpected token: punc «{», expected: punc «,»");
             done();
         });
     });
@@ -281,7 +281,7 @@ describe("bin/uglifyjs", function() {
             assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
             assert.strictEqual(lines[1], "foo, bar(");
             assert.strictEqual(lines[2], "         ^");
-            assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
+            assert.strictEqual(lines[3], "ERROR: Unexpected token: eof");
             done();
         });
     });
@@ -293,7 +293,7 @@ describe("bin/uglifyjs", function() {
             assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
             assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
             assert.strictEqual(lines[2], "                            ^");
-            assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
+            assert.strictEqual(lines[3], "ERROR: Unexpected token: eof");
             done();
         });
     });
@@ -362,7 +362,7 @@ describe("bin/uglifyjs", function() {
                 "Parse error at test/input/invalid/dot_1.js:1,2",
                 "a.=",
                 "  ^",
-                "ERROR: Unexpected token: operator (=)"
+                "ERROR: Unexpected token: operator «=», expected: name"
             ].join("\n"));
             done();
         });
@@ -376,7 +376,7 @@ describe("bin/uglifyjs", function() {
                 "Parse error at test/input/invalid/dot_2.js:1,0",
                 "%.a;",
                 "^",
-                "ERROR: Unexpected token: operator (%)"
+                "ERROR: Unexpected token: operator «%»"
             ].join("\n"));
             done();
         });
@@ -390,7 +390,7 @@ describe("bin/uglifyjs", function() {
                 "Parse error at test/input/invalid/dot_3.js:1,2",
                 "a./();",
                 "  ^",
-                "ERROR: Unexpected token: operator (/)"
+                "ERROR: Unexpected token: operator «/», expected: name"
             ].join("\n"));
             done();
         });
@@ -404,7 +404,7 @@ describe("bin/uglifyjs", function() {
                 "Parse error at test/input/invalid/object.js:1,13",
                 "console.log({%: 1});",
                 "             ^",
-                "ERROR: Unexpected token: operator (%)"
+                "ERROR: Unexpected token: operator «%»"
             ].join("\n"));
             done();
         });
@@ -502,7 +502,7 @@ describe("bin/uglifyjs", function() {
                 "Parse error at test/input/invalid/else.js:1,7",
                 "if (0) else 1;",
                 "       ^",
-                "ERROR: Unexpected token: keyword (else)"
+                "ERROR: Unexpected token: keyword «else»"
             ].join("\n"));
             done();
         });
@@ -633,6 +633,14 @@ describe("bin/uglifyjs", function() {
             done();
         });
     });
+    it("Should work with mangle.properties.regex from --config-file", function(done) {
+        var command = uglifyjscmd + " test/input/issue-3315/input.js --config-file test/input/issue-3315/config.json";
+        exec(command, function(err, stdout) {
+            if (err) throw err;
+            assert.strictEqual(stdout, 'function f(){"aaaaaaaaaa";var a={prop:1,a:2};return a.prop+a.a}\n');
+            done();
+        });
+    });
     it("Should fail with --define a-b", function(done) {
         var command = uglifyjscmd + " test/input/issue-505/input.js --define a-b";
         exec(command, function(err, stdout, stderr) {
index b350a40..1ca1432 100644 (file)
@@ -13,7 +13,7 @@ describe("comments", function() {
 
         var fail = function(e) {
             return e instanceof UglifyJS.JS_Parse_Error
-                && e.message === "Unexpected token: operator (>)"
+                && e.message === "Unexpected token: operator «>»"
                 && e.line === 2
                 && e.col === 0;
         }
@@ -36,7 +36,7 @@ describe("comments", function() {
 
         var fail = function(e) {
             return e instanceof UglifyJS.JS_Parse_Error
-                && e.message === "Unexpected token: operator (>)"
+                && e.message === "Unexpected token: operator «>»"
                 && e.line === 5
                 && e.col === 0;
         }
index 65da6da..74660dc 100644 (file)
@@ -146,7 +146,7 @@ describe("Directives", function() {
                 UglifyJS.parse(tokenizer);
             }, function(e) {
                 return e instanceof UglifyJS.JS_Parse_Error
-                    && e.message === "Unexpected token: punc (])"
+                    && /^Unexpected token: punc «]»/.test(e.message)
             }, test[0]);
             test[1].forEach(function(directive) {
                 assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test[0]);
index 84e7e30..ec811aa 100644 (file)
@@ -69,7 +69,7 @@ describe("Getters and setters", function() {
         var fail = function(data) {
             return function(e) {
                 return e instanceof UglifyJS.JS_Parse_Error
-                    && e.message === "Unexpected token: operator (" + data.operator + ")";
+                    && e.message === "Unexpected token: operator «" + data.operator + "»";
             };
         };
         var errorMessage = function(data) {
index c580e59..6e6c7a7 100644 (file)
@@ -119,7 +119,7 @@ describe("minify", function() {
     it("Should not parse invalid use of reserved words", function() {
         assert.strictEqual(UglifyJS.minify("function enum(){}").error, undefined);
         assert.strictEqual(UglifyJS.minify("function static(){}").error, undefined);
-        assert.strictEqual(UglifyJS.minify("function this(){}").error.message, "Unexpected token: name (this)");
+        assert.strictEqual(UglifyJS.minify("function this(){}").error.message, "Unexpected token: name «this»");
     });
 
     describe("keep_quoted_props", function() {
@@ -214,7 +214,7 @@ describe("minify", function() {
             var result = UglifyJS.minify("function f(a{}");
             var err = result.error;
             assert.ok(err instanceof Error);
-            assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token punc «{», expected punc «,»");
+            assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: punc «{», expected: punc «,»");
             assert.strictEqual(err.filename, "0");
             assert.strictEqual(err.line, 1);
             assert.strictEqual(err.col, 12);
@@ -241,7 +241,7 @@ describe("minify", function() {
             });
             var err = result.error;
             assert.ok(err instanceof Error);
-            assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword (debugger)");
+            assert.strictEqual(err.stack.split(/\n/)[0], "SyntaxError: Unexpected token: keyword «debugger»");
         });
         it("Should skip inherited properties", function() {
             var foo = Object.create({ skip: this });