From abb6aa544f3252e12092c10edacae1c054441a50 Mon Sep 17 00:00:00 2001 From: "Ashley (Scirra)" Date: Wed, 5 Oct 2016 13:39:33 +0100 Subject: [PATCH] Add 'debug' option to mangle_properties Add a 'debug' option to mangle_properties and add a test that verifies it works as expected both with and without a cache passed as well. --- lib/propmangle.js | 23 ++++++++++++++++++++- test/mocha/mangle-debug.js | 42 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/mocha/mangle-debug.js diff --git a/lib/propmangle.js b/lib/propmangle.js index 4187db12..cf436c47 100644 --- a/lib/propmangle.js +++ b/lib/propmangle.js @@ -83,13 +83,20 @@ function mangle_properties(ast, options) { cache : null, only_cache : false, regex : null, - ignore_quoted : false + ignore_quoted : false, + debug : false }); var reserved = options.reserved; if (reserved == null) reserved = find_builtins(); + // To properly simulate different mangling per different invocations, default a random number + // to be appended to each mangled name for this invocation. If a cache is passed, use an empty + // string to correctly simulate using consistent names when caches are passed around. + // (Of course this assumes the same cache is being passed - it's good enough for a debug check though.) + var debugCacheName = Math.floor(Math.random() * 1000).toString(); + var cache = options.cache; if (cache == null) { cache = { @@ -97,9 +104,14 @@ function mangle_properties(ast, options) { props: new Dictionary() }; } + else + { + debugCacheName = ""; + } var regex = options.regex; var ignore_quoted = options.ignore_quoted; + var debug = options.debug; var names_to_mangle = []; var unmangleable = []; @@ -199,6 +211,15 @@ function mangle_properties(ast, options) { if (!should_mangle(name)) { return name; } + + // If debug mode is enabled, return a predictably-mangled name with a prefix and suffix, + // so the name is different but code can still be read for diagnostic purposes. + // Also add the debug cache name which is empty if a (assumedly) consistent cache is + // passed around, otherwise is a random number to ensure separate invocations mangle + // differently as they would in practice. + // e.g. "foo" -> "_$foo$123$_" (or "_$foo$_" with consistent cache) + if (debug) + return "_$" + name + (debugCacheName ? "$" + debugCacheName : "") + "$_"; var mangled = cache.props.get(name); if (!mangled) { diff --git a/test/mocha/mangle-debug.js b/test/mocha/mangle-debug.js new file mode 100644 index 00000000..146449b0 --- /dev/null +++ b/test/mocha/mangle-debug.js @@ -0,0 +1,42 @@ +var Uglify = require('../../'); +var assert = require("assert"); + +describe("mangle_properties 'debug' option ", function() { + it("Should test the 'debug' option of mangle_properties works with no cache passed", function() { + var js = 'var o = {}; o.foo = "bar";'; + + var ast = Uglify.parse(js); + ast.figure_out_scope(); + ast = Uglify.mangle_properties(ast, { + debug: true + }); + + let stream = Uglify.OutputStream(); + ast.print(stream); + var result = stream.toString(); + + // Should match: var o={};o._$foo$NNN$="bar"; + // where NNN is a number. + assert(/var o=\{\};o\._\$foo\$\d+\$_="bar";/.test(result)); + }); + + it("Should test the 'debug' option of mangle_properties works with a cache passed", function() { + var js = 'var o = {}; o.foo = "bar";'; + + var ast = Uglify.parse(js); + ast.figure_out_scope(); + ast = Uglify.mangle_properties(ast, { + cache: { + cname: -1, + props: new Uglify.Dictionary() + }, + debug: true + }); + + let stream = Uglify.OutputStream(); + ast.print(stream); + var result = stream.toString(); + + assert.strictEqual(result, 'var o={};o._$foo$_="bar";'); + }); +});