Add a mode to only mangle unquoted property names

This commit is contained in:
Shrey Banga 2016-06-10 11:55:52 -07:00
parent 2e22da589c
commit 6f3fea60d2
4 changed files with 56 additions and 11 deletions

View File

@ -133,7 +133,11 @@ 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 `1` to only mangle unquoted property names.
Use the `keep_quoted_props` beautifier option to
preserve the quotes around property names.
--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

View File

@ -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)
@ -388,6 +387,10 @@ async.eachLimit(files, 1, function (file, cb) {
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
}
if (ARGS.mangle_props === true) {
ARGS.mangle_props = 1;
}
if (ARGS.mangle_props || ARGS.name_cache) (function(){
var reserved = RESERVED ? RESERVED.props : null;
var cache = readNameCache("props");
@ -401,10 +404,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);
})();

View File

@ -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,11 +90,13 @@ 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
add(node.key.name);
if (!(ignore_quoted && node.key.quote))
add(node.key.name);
}
else if (node instanceof AST_Dot) {
if (this.parent() instanceof AST_Assign) {
@ -101,7 +105,8 @@ function mangle_properties(ast, options) {
}
else if (node instanceof AST_Sub) {
if (this.parent() instanceof AST_Assign) {
addStrings(node.property);
if (!(ignore_quoted && node.property.quote))
addStrings(node.property);
}
}
}));

View File

@ -72,3 +72,35 @@ 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
};
input: {
a["foo"] = "bar";
a.color = "red";
x = {"bar": 10};
}
expect: {
a["foo"] = "bar";
a.a = "red";
x = {"bar": 10};
}
}