From: Alex Lam S.L Date: Thu, 26 Jan 2017 11:18:28 +0000 (+0800) Subject: fix mangling collision with keep_fnames (#1431) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=1eaa211e0932105439d98d4f03a981f157f0a77c;p=UglifyJS.git fix mangling collision with keep_fnames (#1431) * fix mangling collision with keep_fnames fixes #1423 * pass mangle options to figure_out_scope() bring command-line in line with minify() --- diff --git a/bin/uglifyjs b/bin/uglifyjs index 747fb151..8cb2f0df 100755 --- a/bin/uglifyjs +++ b/bin/uglifyjs @@ -428,10 +428,11 @@ async.eachLimit(files, 1, function (file, cb) { var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint var TL_CACHE = readNameCache("vars"); + if (MANGLE) MANGLE.cache = TL_CACHE; if (SCOPE_IS_NEEDED) { time_it("scope", function(){ - TOPLEVEL.figure_out_scope({ screw_ie8: screw_ie8, cache: TL_CACHE }); + TOPLEVEL.figure_out_scope(MANGLE || { screw_ie8: screw_ie8, cache: TL_CACHE }); if (ARGS.lint) { TOPLEVEL.scope_warnings(); } @@ -446,7 +447,7 @@ async.eachLimit(files, 1, function (file, cb) { if (SCOPE_IS_NEEDED) { time_it("scope", function(){ - TOPLEVEL.figure_out_scope({ screw_ie8: screw_ie8, cache: TL_CACHE }); + TOPLEVEL.figure_out_scope(MANGLE || { screw_ie8: screw_ie8, cache: TL_CACHE }); if (MANGLE && !TL_CACHE) { TOPLEVEL.compute_char_frequency(MANGLE); } @@ -454,7 +455,6 @@ async.eachLimit(files, 1, function (file, cb) { } if (MANGLE) time_it("mangle", function(){ - MANGLE.cache = TL_CACHE; TOPLEVEL.mangle_names(MANGLE); }); diff --git a/lib/scope.js b/lib/scope.js index ae792a0a..55d1eff1 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -233,7 +233,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ if (isModified(node, 0)) { sym.modified = true; } - node.reference(); + node.reference(options); return true; } }); @@ -264,13 +264,18 @@ AST_Lambda.DEFMETHOD("init_scope_vars", function(){ this.variables.set(symbol.name, def); }); -AST_SymbolRef.DEFMETHOD("reference", function() { +AST_SymbolRef.DEFMETHOD("reference", function(options) { var def = this.definition(); def.references.push(this); var s = this.scope; while (s) { push_uniq(s.enclosed, def); if (s === def.scope) break; + if (options.keep_fnames) { + s.variables.each(function(d) { + push_uniq(def.scope.enclosed, d); + }); + } s = s.parent_scope; } this.frame = this.scope.nesting - def.scope.nesting; @@ -338,11 +343,6 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){ } }); -AST_Scope.DEFMETHOD("references", function(sym){ - if (sym instanceof AST_Symbol) sym = sym.definition(); - return this.enclosed.indexOf(sym) < 0 ? null : sym; -}); - AST_Symbol.DEFMETHOD("unmangleable", function(options){ return this.definition().unmangleable(options); }); diff --git a/test/compress/issue-1431.js b/test/compress/issue-1431.js new file mode 100644 index 00000000..731ebba8 --- /dev/null +++ b/test/compress/issue-1431.js @@ -0,0 +1,122 @@ +level_one: { + options = { + keep_fnames: true + } + mangle = { + keep_fnames: true + } + input: { + function f(x) { + return function() { + function n(a) { + return a * a; + } + return x(n); + }; + } + } + expect: { + function f(r) { + return function() { + function n(n) { + return n * n; + } + return r(n); + }; + } + } +} + +level_two: { + options = { + keep_fnames: true + } + mangle = { + keep_fnames: true + } + input: { + function f(x) { + return function() { + function r(a) { + return a * a; + } + return function() { + function n(a) { + return a * a; + } + return x(n); + }; + }; + } + } + expect: { + function f(t) { + return function() { + function r(n) { + return n * n; + } + return function() { + function n(n) { + return n * n; + } + return t(n); + }; + }; + } + } +} + +level_three: { + options = { + keep_fnames: true + } + mangle = { + keep_fnames: true + } + input: { + function f(x) { + return function() { + function r(a) { + return a * a; + } + return [ + function() { + function t(a) { + return a * a; + } + return t; + }, + function() { + function n(a) { + return a * a; + } + return x(n); + } + ]; + }; + } + } + expect: { + function f(t) { + return function() { + function r(n) { + return n * n; + } + return [ + function() { + function t(n) { + return n * n; + } + return t; + }, + function() { + function n(n) { + return n * n; + } + return t(n); + } + ]; + }; + } + } +} diff --git a/test/input/issue-1431/sample.js b/test/input/issue-1431/sample.js new file mode 100644 index 00000000..32068cb2 --- /dev/null +++ b/test/input/issue-1431/sample.js @@ -0,0 +1,14 @@ +function f(x) { + return function() { + function n(a) { + return a * a; + } + return x(n); + }; +} + +function g(op) { + return op(1) + op(2); +} + +console.log(f(g)() == 5); \ No newline at end of file diff --git a/test/mocha/cli.js b/test/mocha/cli.js index bebd4d9d..a8de05c5 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -55,7 +55,7 @@ describe("bin/uglifyjs", function () { exec(command, function (err, stdout) { if (err) throw err; - assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" + + assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" + "//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=\n"); done(); }); @@ -70,4 +70,34 @@ describe("bin/uglifyjs", function () { done(); }); }); + it("Should work with --keep-fnames (mangle only)", function (done) { + var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m'; + + exec(command, function (err, stdout) { + if (err) throw err; + + assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n"); + done(); + }); + }); + it("Should work with --keep-fnames (mangle & compress)", function (done) { + var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c'; + + exec(command, function (err, stdout) { + if (err) throw err; + + assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n"); + done(); + }); + }); + it("Should work with keep_fnames under mangler options", function (done) { + var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fnames=true'; + + exec(command, function (err, stdout) { + if (err) throw err; + + assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n"); + done(); + }); + }); });