Fix mangling of property names which overwrite unmangleable properties
authorRichard van Velzen <rvanvelzen@experty.com>
Fri, 31 Jul 2015 13:56:33 +0000 (15:56 +0200)
committerRichard van Velzen <rvanvelzen@experty.com>
Wed, 5 Aug 2015 19:18:39 +0000 (21:18 +0200)
Fixes #747.

lib/propmangle.js
test/compress/issue-747.js [new file with mode: 0644]
test/run-tests.js

index 086709e..840bda9 100644 (file)
@@ -83,6 +83,7 @@ function mangle_properties(ast, options) {
     var regex = options.regex;
 
     var names_to_mangle = [];
+    var unmangleable = [];
 
     // step 1: find candidates to mangle
     ast.walk(new TreeWalker(function(node){
@@ -108,20 +109,14 @@ function mangle_properties(ast, options) {
     // step 2: transform the tree, renaming properties
     return ast.transform(new TreeTransformer(function(node){
         if (node instanceof AST_ObjectKeyVal) {
-            if (should_mangle(node.key)) {
-                node.key = mangle(node.key);
-            }
+            node.key = mangle(node.key);
         }
         else if (node instanceof AST_ObjectProperty) {
             // setter or getter
-            if (should_mangle(node.key.name)) {
-                node.key.name = mangle(node.key.name);
-            }
+            node.key.name = mangle(node.key.name);
         }
         else if (node instanceof AST_Dot) {
-            if (should_mangle(node.property)) {
-                node.property = mangle(node.property);
-            }
+            node.property = mangle(node.property);
         }
         else if (node instanceof AST_Sub) {
             node.property = mangleStrings(node.property);
@@ -143,6 +138,7 @@ function mangle_properties(ast, options) {
     // only function declarations after this line
 
     function can_mangle(name) {
+        if (unmangleable.indexOf(name) >= 0) return false;
         if (reserved.indexOf(name) >= 0) return false;
         if (options.only_cache) {
             return cache.props.has(name);
@@ -161,9 +157,17 @@ function mangle_properties(ast, options) {
     function add(name) {
         if (can_mangle(name))
             push_uniq(names_to_mangle, name);
+
+        if (!should_mangle(name)) {
+            push_uniq(unmangleable, name);
+        }
     }
 
     function mangle(name) {
+        if (!should_mangle(name)) {
+            return name;
+        }
+
         var mangled = cache.props.get(name);
         if (!mangled) {
             do {
@@ -206,9 +210,7 @@ function mangle_properties(ast, options) {
                 node.cdr = mangleStrings(node.cdr);
             }
             else if (node instanceof AST_String) {
-                if (should_mangle(node.value)) {
-                    node.value = mangle(node.value);
-                }
+                node.value = mangle(node.value);
             }
             else if (node instanceof AST_Conditional) {
                 node.consequent = mangleStrings(node.consequent);
diff --git a/test/compress/issue-747.js b/test/compress/issue-747.js
new file mode 100644 (file)
index 0000000..0a4e450
--- /dev/null
@@ -0,0 +1,37 @@
+dont_reuse_prop: {
+    mangle_props = {
+        regex: /asd/
+    };
+
+    input: {
+        var obj = {};
+        obj.a = 123;
+        obj.asd = 256;
+        console.log(obj.a);
+    }
+    expect: {
+        var obj = {};
+        obj.a = 123;
+        obj.b = 256;
+        console.log(obj.a);
+    }
+}
+
+unmangleable_props_should_always_be_reserved: {
+    mangle_props = {
+        regex: /asd/
+    };
+
+    input: {
+        var obj = {};
+        obj.asd = 256;
+        obj.a = 123;
+        console.log(obj.a);
+    }
+    expect: {
+        var obj = {};
+        obj.b = 256;
+        obj.a = 123;
+        console.log(obj.a);
+    }
+}
\ No newline at end of file
index d97e5cf..fc7476f 100755 (executable)
@@ -92,6 +92,9 @@ function run_compress_tests() {
             }
             var input = as_toplevel(test.input);
             var input_code = make_code(test.input);
+            if (test.mangle_props) {
+                input = U.mangle_properties(input, test.mangle_props);
+            }
             var output = input.transform(cmp);
             output.figure_out_scope();
             output = make_code(output, false);