[Pkg-javascript-commits] [uglifyjs] 169/190: Respect quote style in object literals

Antonio Terceiro terceiro at moszumanska.debian.org
Sun Aug 7 23:17:23 UTC 2016


This is an automated email from the git hooks/post-receive script.

terceiro pushed a commit to annotated tag upstream/2.7.0
in repository uglifyjs.

commit e645ba84cfc950183a222c2cce2ea6b94fe51226
Author: Shrey Banga <shrey at quip.com>
Date:   Thu May 5 13:44:59 2016 -0700

    Respect quote style in object literals
    
    The option added in fbbaa42ee55a7f753f7cab9b1a905ccf73cf26d5 wasn't
    being respected inside object literals, so quoted property names would
    still be stripped out with this option.
    
    This is mostly a corner-case, but useful when the output is passed to
    something like the Closure compiler, where quoted property names can be
    used to prevent mangling.
---
 README.md                   | 16 ++++++++++++--
 bin/uglifyjs                | 24 +++++++++++++++-----
 lib/output.js               |  9 ++++++--
 lib/propmangle.js           | 16 +++++++++-----
 test/compress/properties.js | 51 +++++++++++++++++++++++++++++++++++++++++++
 test/mocha/minify.js        | 53 ++++++++++++++++++++++++++++++++++++++++++++-
 test/run-tests.js           |  6 ++++-
 7 files changed, 158 insertions(+), 17 deletions(-)

diff --git a/README.md b/README.md
index 51d0b62..293608e 100644
--- a/README.md
+++ b/README.md
@@ -133,7 +133,16 @@ The available options are:
   --reserved-file               File containing reserved names
   --reserve-domprops            Make (most?) DOM properties reserved for
                                 --mangle-props
-  --mangle-props                Mangle property names
+  --mangle-props                Mangle property names (default `0`). Set to 
+                                `true` or `1` to mangle all property names. Set
+                                to `unquoted` or `2` to only mangle unquoted 
+                                property names. Mode `2` also enables the
+                                `keep_quoted_props` beautifier option to 
+                                preserve the quotes around property names and
+                                disables the `properties` compressor option to
+                                prevent rewriting quoted properties with dot
+                                notation. You can override these by setting
+                                them explicitly on the command line.
   --mangle-regex                Only mangle property names matching the regex
   --name-cache                  File to hold mangled names mappings
   --pure-funcs                  List of functions that can be safely removed if
@@ -479,6 +488,8 @@ can pass additional arguments that control the code output:
   - `1` -- always use single quotes
   - `2` -- always use double quotes
   - `3` -- always use the original quotes
+- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
+  quotes from property names in object literals.
 
 ### Keeping copyright notices or other comments
 
@@ -667,7 +678,8 @@ Other options:
 
 ##### mangleProperties options
 
- - `regex` — Pass a RegExp to only mangle certain names (maps to the `--mange-regex` CLI arguments option)
+ - `regex` — Pass a RegExp to only mangle certain names (maps to the `--mangle-regex` CLI arguments option)
+ - `ignore_quoted` – Only mangle unquoted property names (maps to the `--mangle-props 2` CLI arguments option)
 
 We could add more options to `UglifyJS.minify` — if you need additional
 functionality please suggest!
diff --git a/bin/uglifyjs b/bin/uglifyjs
index 45c92b5..b700942 100755
--- a/bin/uglifyjs
+++ b/bin/uglifyjs
@@ -69,7 +69,7 @@ You need to pass an argument to this option to specify the name that your module
     .describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)")
     .describe("reserved-file", "File containing reserved names")
     .describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props")
-    .describe("mangle-props", "Mangle property names")
+    .describe("mangle-props", "Mangle property names (0 - disabled, 1 - mangle all properties, 2 - mangle unquoted properies)")
     .describe("mangle-regex", "Only mangle property names matching the regex")
     .describe("name-cache", "File to hold mangled names mappings")
     .describe("pure-funcs", "List of functions that can be safely removed if their return value is not used")
@@ -125,7 +125,6 @@ You need to pass an argument to this option to specify the name that your module
     .boolean("noerr")
     .boolean("bare-returns")
     .boolean("keep-fnames")
-    .boolean("mangle-props")
     .boolean("reserve-domprops")
 
     .wrap(80)
@@ -213,12 +212,24 @@ if (ARGS.quotes === true) {
     ARGS.quotes = 3;
 }
 
+if (ARGS.mangle_props === true) {
+    ARGS.mangle_props = 1;
+} else if (ARGS.mangle_props === "unquoted") {
+    ARGS.mangle_props = 2;
+}
+
 var OUTPUT_OPTIONS = {
     beautify    : BEAUTIFY ? true : false,
     preamble    : ARGS.preamble || null,
     quote_style : ARGS.quotes != null ? ARGS.quotes : 0
 };
 
+if (ARGS.mangle_props == 2) {
+    OUTPUT_OPTIONS.keep_quoted_props = true;
+    if (COMPRESS && !("properties" in COMPRESS))
+        COMPRESS.properties = false;
+}
+
 if (ARGS.screw_ie8) {
     if (COMPRESS) COMPRESS.screw_ie8 = true;
     if (MANGLE) MANGLE.screw_ie8 = true;
@@ -401,10 +412,11 @@ async.eachLimit(files, 1, function (file, cb) {
         }
 
         TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
-            reserved   : reserved,
-            cache      : cache,
-            only_cache : !ARGS.mangle_props,
-            regex      : regex
+            reserved      : reserved,
+            cache         : cache,
+            only_cache    : !ARGS.mangle_props,
+            regex         : regex,
+            ignore_quoted : ARGS.mangle_props == 2
         });
         writeNameCache("props", cache);
     })();
diff --git a/lib/output.js b/lib/output.js
index 1fa9899..10465e2 100644
--- a/lib/output.js
+++ b/lib/output.js
@@ -66,7 +66,8 @@ function OutputStream(options) {
         preserve_line    : false,
         screw_ie8        : false,
         preamble         : null,
-        quote_style      : 0
+        quote_style      : 0,
+        keep_quoted_props: false
     }, true);
 
     var indentation = 0;
@@ -1173,7 +1174,11 @@ function OutputStream(options) {
                    && parseFloat(key) >= 0) {
             output.print(make_num(key));
         } else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) {
-            output.print_name(key);
+            if (quote && output.option("keep_quoted_props")) {
+                output.print_string(key, quote);
+            } else {
+                output.print_name(key);
+            }
         } else {
             output.print_string(key, quote);
         }
diff --git a/lib/propmangle.js b/lib/propmangle.js
index 840bda9..08043d7 100644
--- a/lib/propmangle.js
+++ b/lib/propmangle.js
@@ -65,7 +65,8 @@ function mangle_properties(ast, options) {
         reserved : null,
         cache : null,
         only_cache : false,
-        regex : null
+        regex : null,
+        ignore_quoted : false
     });
 
     var reserved = options.reserved;
@@ -81,6 +82,7 @@ function mangle_properties(ast, options) {
     }
 
     var regex = options.regex;
+    var ignore_quoted = options.ignore_quoted;
 
     var names_to_mangle = [];
     var unmangleable = [];
@@ -88,7 +90,8 @@ function mangle_properties(ast, options) {
     // step 1: find candidates to mangle
     ast.walk(new TreeWalker(function(node){
         if (node instanceof AST_ObjectKeyVal) {
-            add(node.key);
+            if (!(ignore_quoted && node.quote))
+                add(node.key);
         }
         else if (node instanceof AST_ObjectProperty) {
             // setter or getter, since KeyVal is handled above
@@ -101,7 +104,8 @@ function mangle_properties(ast, options) {
         }
         else if (node instanceof AST_Sub) {
             if (this.parent() instanceof AST_Assign) {
-                addStrings(node.property);
+                if (!ignore_quoted)
+                    addStrings(node.property);
             }
         }
     }));
@@ -109,7 +113,8 @@ function mangle_properties(ast, options) {
     // step 2: transform the tree, renaming properties
     return ast.transform(new TreeTransformer(function(node){
         if (node instanceof AST_ObjectKeyVal) {
-            node.key = mangle(node.key);
+            if (!(ignore_quoted && node.quote))
+                node.key = mangle(node.key);
         }
         else if (node instanceof AST_ObjectProperty) {
             // setter or getter
@@ -119,7 +124,8 @@ function mangle_properties(ast, options) {
             node.property = mangle(node.property);
         }
         else if (node instanceof AST_Sub) {
-            node.property = mangleStrings(node.property);
+            if (!ignore_quoted)
+                node.property = mangleStrings(node.property);
         }
         // else if (node instanceof AST_String) {
         //     if (should_mangle(node.value)) {
diff --git a/test/compress/properties.js b/test/compress/properties.js
index 3947073..574c514 100644
--- a/test/compress/properties.js
+++ b/test/compress/properties.js
@@ -72,3 +72,54 @@ evaluate_length: {
         a = ("foo" + b).length;
     }
 }
+
+mangle_properties: {
+    mangle_props = {
+        ignore_quoted: false
+    };
+    input: {
+        a["foo"] = "bar";
+        a.color = "red";
+        x = {"bar": 10};
+    }
+    expect: {
+        a["a"] = "bar";
+        a.b = "red";
+        x = {c: 10};
+    }
+}
+
+mangle_unquoted_properties: {
+    mangle_props = {
+        ignore_quoted: true
+    }
+    beautify = {
+        beautify: false,
+        quote_style: 3,
+        keep_quoted_props: true,
+    }
+    input: {
+        function f1() {
+            a["foo"] = "bar";
+            a.color = "red";
+            x = {"bar": 10};
+        }
+        function f2() {
+            a.foo = "bar";
+            a['color'] = "red";
+            x = {bar: 10};
+        }
+    }
+    expect: {
+        function f1() {
+            a["foo"] = "bar";
+            a.a = "red";
+            x = {"bar": 10};
+        }
+        function f2() {
+            a.b = "bar";
+            a['color'] = "red";
+            x = {c: 10};
+        }
+    }
+}
diff --git a/test/mocha/minify.js b/test/mocha/minify.js
index bbf188c..02d3155 100644
--- a/test/mocha/minify.js
+++ b/test/mocha/minify.js
@@ -7,5 +7,56 @@ describe("minify", function() {
         var result = Uglify.minify(js, {fromString: true});
         assert.strictEqual(result.code, 'function foo(n){return n?3:7}');
     });
-});
 
+    describe("keep_quoted_props", function() {
+        it("Should preserve quotes in object literals", function() {
+            var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
+            var result = Uglify.minify(js, {
+                fromString: true, output: {
+                    keep_quoted_props: true
+                }});
+            assert.strictEqual(result.code, 'var foo={"x":1,y:2,"z":3};');
+        });
+
+        it("Should preserve quote styles when quote_style is 3", function() {
+            var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
+            var result = Uglify.minify(js, {
+                fromString: true, output: {
+                    keep_quoted_props: true,
+                    quote_style: 3
+                }});
+            assert.strictEqual(result.code, 'var foo={"x":1,y:2,\'z\':3};');
+        });
+
+        it("Should not preserve quotes in object literals when disabled", function() {
+            var js = 'var foo = {"x": 1, y: 2, \'z\': 3};';
+            var result = Uglify.minify(js, {
+                fromString: true, output: {
+                    keep_quoted_props: false,
+                    quote_style: 3
+                }});
+            assert.strictEqual(result.code, 'var foo={x:1,y:2,z:3};');
+        });
+    });
+
+    describe("mangleProperties", function() {
+        it("Shouldn't mangle quoted properties", function() {
+            var js = 'a["foo"] = "bar"; a.color = "red"; x = {"bar": 10};';
+            var result = Uglify.minify(js, {
+                fromString: true,
+                compress: {
+                    properties: false
+                },
+                mangleProperties: {
+                    ignore_quoted: true
+                },
+                output: {
+                    keep_quoted_props: true,
+                    quote_style: 3
+                }
+            });
+            assert.strictEqual(result.code,
+                    'a["foo"]="bar",a.a="red",x={"bar":10};');
+        });
+    });
+});
diff --git a/test/run-tests.js b/test/run-tests.js
index 5fc69c6..0fdee6f 100755
--- a/test/run-tests.js
+++ b/test/run-tests.js
@@ -108,7 +108,11 @@ function run_compress_tests() {
                 expect = test.expect_exact;
             }
             var input = as_toplevel(test.input);
-            var input_code = make_code(test.input, { beautify: true });
+            var input_code = make_code(test.input, {
+                beautify: true,
+                quote_style: 3,
+                keep_quoted_props: true
+            });
             if (test.mangle_props) {
                 input = U.mangle_properties(input, test.mangle_props);
             }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/uglifyjs.git



More information about the Pkg-javascript-commits mailing list